@getpaseo/server 0.1.104-beta.2 → 0.1.104-beta.3

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 (49) hide show
  1. package/dist/server/server/agent/create-agent/create.d.ts +1 -1
  2. package/dist/server/server/agent/create-agent/create.js +4 -4
  3. package/dist/server/server/agent/providers/claude/agent.js +3 -2
  4. package/dist/server/server/agent/providers/claude/feature-definitions.js +2 -14
  5. package/dist/server/server/agent/providers/claude/model-manifest.d.ts +90 -0
  6. package/dist/server/server/agent/providers/claude/model-manifest.js +205 -0
  7. package/dist/server/server/agent/providers/claude/models.js +4 -141
  8. package/dist/server/server/agent/tools/paseo-tools.d.ts +4 -1
  9. package/dist/server/server/agent/tools/paseo-tools.js +73 -4
  10. package/dist/server/server/bootstrap.js +37 -3
  11. package/dist/server/server/browser-tools/broker.d.ts +16 -5
  12. package/dist/server/server/browser-tools/broker.js +220 -22
  13. package/dist/server/server/browser-tools/tools.js +195 -36
  14. package/dist/server/server/session.d.ts +3 -10
  15. package/dist/server/server/session.js +10 -121
  16. package/dist/server/server/websocket-server.d.ts +3 -1
  17. package/dist/server/server/websocket-server.js +18 -5
  18. package/dist/server/server/workspace-auto-name.d.ts +55 -0
  19. package/dist/server/server/workspace-auto-name.js +128 -0
  20. package/dist/server/server/worktree-session.d.ts +1 -1
  21. package/dist/server/server/worktree-session.js +1 -1
  22. package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-d9e471546cbc685a5f1a44f54114fc48.js → desktop-attachment-bridge-95a8163efd836849dd3f83730f1e84f4.js} +1 -1
  23. package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-bridge-d9e471546cbc685a5f1a44f54114fc48.js.br → desktop-attachment-bridge-95a8163efd836849dd3f83730f1e84f4.js.br} +0 -0
  24. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-95a8163efd836849dd3f83730f1e84f4.js.gz +0 -0
  25. package/dist/server/web-ui/_expo/static/js/web/{desktop-attachment-store-30526c06e214c5937e98bf1e5244cc22.js → desktop-attachment-store-9b3937a7b33a31908fa313b18c15daf6.js} +1 -1
  26. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-9b3937a7b33a31908fa313b18c15daf6.js.br +0 -0
  27. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-9b3937a7b33a31908fa313b18c15daf6.js.gz +0 -0
  28. package/dist/server/web-ui/_expo/static/js/web/{index-9f718c794c8b2995afa4a8f14218e814.js → index-690d9fe101525c0a632093e00322c944.js} +1056 -1055
  29. package/dist/server/web-ui/_expo/static/js/web/index-690d9fe101525c0a632093e00322c944.js.br +0 -0
  30. package/dist/server/web-ui/_expo/static/js/web/index-690d9fe101525c0a632093e00322c944.js.gz +0 -0
  31. package/dist/server/web-ui/_expo/static/js/web/{indexeddb-attachment-store-aa960ad0ab4cef263d0d7664e12f5b65.js → indexeddb-attachment-store-ee4a35a8c1da1c737256427f2fe19c35.js} +1 -1
  32. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-ee4a35a8c1da1c737256427f2fe19c35.js.br +0 -0
  33. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-ee4a35a8c1da1c737256427f2fe19c35.js.gz +0 -0
  34. package/dist/server/web-ui/_expo/static/js/web/{native-file-attachment-store-7837a7115a8a584b7d7231cfa2eae2cf.js → native-file-attachment-store-c4aebe23af349f0f64f418e755c84c00.js} +3 -3
  35. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-c4aebe23af349f0f64f418e755c84c00.js.br +0 -0
  36. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-c4aebe23af349f0f64f418e755c84c00.js.gz +0 -0
  37. package/dist/server/web-ui/index.html +1 -1
  38. package/dist/server/web-ui/index.html.br +0 -0
  39. package/dist/server/web-ui/index.html.gz +0 -0
  40. package/package.json +5 -5
  41. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-bridge-d9e471546cbc685a5f1a44f54114fc48.js.gz +0 -0
  42. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-30526c06e214c5937e98bf1e5244cc22.js.br +0 -0
  43. package/dist/server/web-ui/_expo/static/js/web/desktop-attachment-store-30526c06e214c5937e98bf1e5244cc22.js.gz +0 -0
  44. package/dist/server/web-ui/_expo/static/js/web/index-9f718c794c8b2995afa4a8f14218e814.js.br +0 -0
  45. package/dist/server/web-ui/_expo/static/js/web/index-9f718c794c8b2995afa4a8f14218e814.js.gz +0 -0
  46. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-aa960ad0ab4cef263d0d7664e12f5b65.js.br +0 -0
  47. package/dist/server/web-ui/_expo/static/js/web/indexeddb-attachment-store-aa960ad0ab4cef263d0d7664e12f5b65.js.gz +0 -0
  48. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-7837a7115a8a584b7d7231cfa2eae2cf.js.br +0 -0
  49. package/dist/server/web-ui/_expo/static/js/web/native-file-attachment-store-7837a7115a8a584b7d7231cfa2eae2cf.js.gz +0 -0
@@ -14,6 +14,16 @@ const BrowserToolOutputSchema = {
14
14
  retryable: z.boolean(),
15
15
  })
16
16
  .optional(),
17
+ dialogs: z
18
+ .array(z.object({
19
+ type: z.enum(["alert", "confirm", "prompt", "beforeunload"]),
20
+ message: z.string(),
21
+ defaultValue: z.string().optional(),
22
+ action: z.enum(["accepted", "dismissed"]),
23
+ promptText: z.string().optional(),
24
+ timestamp: z.number(),
25
+ }))
26
+ .optional(),
17
27
  context: z
18
28
  .object({
19
29
  agentId: z.string().optional(),
@@ -38,6 +48,8 @@ const BrowserHttpUrlInputSchema = z
38
48
  return normalized;
39
49
  });
40
50
  const BrowserRefInputSchema = z.string().regex(/^@e\d+$/);
51
+ const BrowserClickButtonInputSchema = z.enum(["left", "right", "middle"]);
52
+ const BrowserClickModifierInputSchema = z.enum(["Alt", "Control", "Meta", "Shift"]);
41
53
  const BrowserWaitInputSchema = z
42
54
  .object({
43
55
  text: z.string().min(1).optional(),
@@ -51,7 +63,7 @@ const BrowserWaitInputSchema = z
51
63
  export function registerBrowserTools(options) {
52
64
  options.registerTool("browser_list_tabs", {
53
65
  title: "List browser tabs",
54
- description: "List open Paseo desktop browser tabs for this agent's workspace. Use returned browserId values with tab-scoped tools.",
66
+ description: "List open Paseo browser tabs for this agent's workspace across connected browser automation hosts. Use returned browserId values with tab-scoped tools.",
55
67
  inputSchema: {},
56
68
  outputSchema: BrowserToolOutputSchema,
57
69
  }, async () => {
@@ -73,7 +85,7 @@ export function registerBrowserTools(options) {
73
85
  });
74
86
  options.registerTool("browser_new_tab", {
75
87
  title: "Create browser tab",
76
- description: "Create and focus a new Paseo desktop browser tab in this agent's workspace. Pass an http(s) URL or a scheme-less host URL, which is treated as http; the returned browserId is used by tab-scoped tools.",
88
+ description: "Create a new Paseo browser tab in this agent's workspace on the most recently connected browser automation host, opened in the background without switching the user's view. Pass an http(s) URL or a scheme-less host URL, which is treated as http; the returned browserId is used by tab-scoped tools.",
77
89
  inputSchema: {
78
90
  url: BrowserHttpUrlInputSchema.optional(),
79
91
  },
@@ -97,7 +109,7 @@ export function registerBrowserTools(options) {
97
109
  });
98
110
  options.registerTool("browser_snapshot", {
99
111
  title: "Snapshot browser page",
100
- description: "Return a model-readable snapshot of a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
112
+ description: "Return a model-readable snapshot of a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
101
113
  inputSchema: {
102
114
  browserId: BrowserAutomationBrowserIdSchema,
103
115
  },
@@ -119,13 +131,16 @@ export function registerBrowserTools(options) {
119
131
  });
120
132
  options.registerTool("browser_click", {
121
133
  title: "Click browser element",
122
- description: "Click an element in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
134
+ description: "Click an element in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
123
135
  inputSchema: {
124
136
  ref: BrowserRefInputSchema,
125
137
  browserId: BrowserAutomationBrowserIdSchema,
138
+ button: BrowserClickButtonInputSchema.optional(),
139
+ doubleClick: z.boolean().optional(),
140
+ modifiers: z.array(BrowserClickModifierInputSchema).optional(),
126
141
  },
127
142
  outputSchema: BrowserToolOutputSchema,
128
- }, async ({ ref, browserId }) => {
143
+ }, async ({ ref, browserId, button, doubleClick, modifiers }) => {
129
144
  const context = resolveBrowserToolContext(options);
130
145
  const payload = await options.broker.execute({
131
146
  agentId: context.agentId,
@@ -136,6 +151,9 @@ export function registerBrowserTools(options) {
136
151
  args: {
137
152
  browserId,
138
153
  ref,
154
+ button: button ?? "left",
155
+ doubleClick: doubleClick ?? false,
156
+ modifiers: modifiers ?? [],
139
157
  },
140
158
  },
141
159
  });
@@ -143,7 +161,7 @@ export function registerBrowserTools(options) {
143
161
  });
144
162
  options.registerTool("browser_fill", {
145
163
  title: "Fill browser element",
146
- description: "Fill an input-like element in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
164
+ description: "Fill an input-like element in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
147
165
  inputSchema: {
148
166
  ref: BrowserRefInputSchema,
149
167
  value: z.string(),
@@ -169,7 +187,7 @@ export function registerBrowserTools(options) {
169
187
  });
170
188
  options.registerTool("browser_wait", {
171
189
  title: "Wait for browser condition",
172
- description: "Wait until a Paseo desktop browser tab contains text or reaches a URL fragment. Use browserId from browser_new_tab or browser_list_tabs; waits up to 5s by default on the desktop side.",
190
+ description: "Wait until a Paseo browser tab contains text or reaches a URL fragment. Use browserId from browser_new_tab or browser_list_tabs; waits up to 5s by default on the browser host.",
173
191
  inputSchema: BrowserWaitInputSchema,
174
192
  outputSchema: BrowserToolOutputSchema,
175
193
  }, async ({ text, url, timeoutMs, browserId }) => {
@@ -245,7 +263,7 @@ export function registerBrowserTools(options) {
245
263
  });
246
264
  options.registerTool("browser_navigate", {
247
265
  title: "Navigate browser",
248
- description: "Navigate a Paseo desktop browser tab to a URL. Use browserId from browser_new_tab or browser_list_tabs; pass an http(s) URL or a scheme-less host URL, which is treated as http.",
266
+ description: "Navigate a Paseo browser tab to a URL. Use browserId from browser_new_tab or browser_list_tabs; pass an http(s) URL or a scheme-less host URL, which is treated as http.",
249
267
  inputSchema: { url: BrowserHttpUrlInputSchema, browserId: BrowserAutomationBrowserIdSchema },
250
268
  outputSchema: BrowserToolOutputSchema,
251
269
  }, async ({ url, browserId }) => {
@@ -269,19 +287,19 @@ export function registerBrowserTools(options) {
269
287
  name: "browser_back",
270
288
  command: "back",
271
289
  title: "Browser back",
272
- description: "Go back in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
290
+ description: "Go back in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
273
291
  },
274
292
  {
275
293
  name: "browser_forward",
276
294
  command: "forward",
277
295
  title: "Browser forward",
278
- description: "Go forward in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
296
+ description: "Go forward in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
279
297
  },
280
298
  {
281
299
  name: "browser_reload",
282
300
  command: "reload",
283
301
  title: "Browser reload",
284
- description: "Reload a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
302
+ description: "Reload a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs.",
285
303
  },
286
304
  ]) {
287
305
  options.registerTool(toolConfig.name, {
@@ -307,7 +325,7 @@ export function registerBrowserTools(options) {
307
325
  }
308
326
  options.registerTool("browser_screenshot", {
309
327
  title: "Capture browser screenshot",
310
- description: "Capture a PNG screenshot of a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs. Set fullPage to true to capture the full page.",
328
+ description: "Capture a PNG screenshot of a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs. Set fullPage to true to capture the full page.",
311
329
  inputSchema: {
312
330
  browserId: BrowserAutomationBrowserIdSchema,
313
331
  fullPage: z.boolean().default(false),
@@ -331,7 +349,7 @@ export function registerBrowserTools(options) {
331
349
  });
332
350
  options.registerTool("browser_upload", {
333
351
  title: "Upload files in browser",
334
- description: "Set workspace files on a file input in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
352
+ description: "Set workspace files on a file input in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
335
353
  inputSchema: {
336
354
  ref: BrowserRefInputSchema,
337
355
  filePaths: z.array(z.string().min(1)).min(1),
@@ -360,7 +378,7 @@ export function registerBrowserTools(options) {
360
378
  name: "browser_hover",
361
379
  command: "hover",
362
380
  title: "Hover browser element",
363
- description: "Hover an element in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
381
+ description: "Hover an element in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
364
382
  },
365
383
  ]) {
366
384
  options.registerTool(toolConfig.name, {
@@ -387,7 +405,7 @@ export function registerBrowserTools(options) {
387
405
  }
388
406
  options.registerTool("browser_select", {
389
407
  title: "Select browser option",
390
- description: "Set a select element in a Paseo desktop browser tab to a value. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
408
+ description: "Set a select element in a Paseo browser tab to a value. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
391
409
  inputSchema: {
392
410
  ref: BrowserRefInputSchema,
393
411
  value: z.string(),
@@ -413,7 +431,7 @@ export function registerBrowserTools(options) {
413
431
  });
414
432
  options.registerTool("browser_drag", {
415
433
  title: "Drag browser element",
416
- description: "Drag one element onto another in a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
434
+ description: "Drag one element onto another in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; refs come from the latest browser_snapshot of the same tab and expire when the page changes.",
417
435
  inputSchema: {
418
436
  sourceRef: BrowserRefInputSchema,
419
437
  targetRef: BrowserRefInputSchema,
@@ -439,7 +457,7 @@ export function registerBrowserTools(options) {
439
457
  });
440
458
  options.registerTool("browser_logs", {
441
459
  title: "Read browser logs",
442
- description: "Read recent console messages and browser performance network entries for a Paseo desktop browser tab. Use browserId from browser_new_tab or browser_list_tabs; maxEntries defaults to 50.",
460
+ description: "Read recent console messages and browser performance network entries for a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; maxEntries defaults to 50.",
443
461
  inputSchema: {
444
462
  maxEntries: z.number().int().positive().max(200).optional(),
445
463
  browserId: BrowserAutomationBrowserIdSchema,
@@ -461,6 +479,108 @@ export function registerBrowserTools(options) {
461
479
  });
462
480
  return browserToolResult({ payload, context: { ...context, browserId } });
463
481
  });
482
+ options.registerTool("browser_evaluate", {
483
+ title: "Evaluate browser JavaScript",
484
+ description: "Evaluate a JavaScript function in a Paseo browser tab. Use browserId from browser_new_tab or browser_list_tabs; when ref is provided, refs come from the latest browser_snapshot and the resolved element is passed as the first argument.",
485
+ inputSchema: {
486
+ function: z.string().min(1),
487
+ ref: BrowserRefInputSchema.optional(),
488
+ browserId: BrowserAutomationBrowserIdSchema,
489
+ },
490
+ outputSchema: BrowserToolOutputSchema,
491
+ }, async ({ function: functionSource, ref, browserId }) => {
492
+ const context = resolveBrowserToolContext(options);
493
+ const payload = await options.broker.execute({
494
+ agentId: context.agentId,
495
+ cwd: context.cwd,
496
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {}),
497
+ command: {
498
+ command: "evaluate",
499
+ args: {
500
+ browserId,
501
+ function: functionSource,
502
+ ...(ref ? { ref } : {}),
503
+ },
504
+ },
505
+ });
506
+ return browserToolResult({ payload, context: { ...context, browserId } });
507
+ });
508
+ options.registerTool("browser_scroll", {
509
+ title: "Scroll browser",
510
+ description: "Scroll a Paseo browser tab by deltaX/deltaY CSS pixels. Use browserId from browser_new_tab or browser_list_tabs; optional ref comes from the latest browser_snapshot and centers the wheel input over that element.",
511
+ inputSchema: {
512
+ browserId: BrowserAutomationBrowserIdSchema,
513
+ ref: BrowserRefInputSchema.optional(),
514
+ deltaX: z.number(),
515
+ deltaY: z.number(),
516
+ },
517
+ outputSchema: BrowserToolOutputSchema,
518
+ }, async ({ browserId, ref, deltaX, deltaY }) => {
519
+ const context = resolveBrowserToolContext(options);
520
+ const payload = await options.broker.execute({
521
+ agentId: context.agentId,
522
+ cwd: context.cwd,
523
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {}),
524
+ command: {
525
+ command: "scroll",
526
+ args: {
527
+ browserId,
528
+ ...(ref ? { ref } : {}),
529
+ deltaX,
530
+ deltaY,
531
+ },
532
+ },
533
+ });
534
+ return browserToolResult({ payload, context: { ...context, browserId } });
535
+ });
536
+ options.registerTool("browser_resize", {
537
+ title: "Resize browser viewport",
538
+ description: "Resize a Paseo browser tab's resident webview viewport. Use browserId from browser_new_tab or browser_list_tabs.",
539
+ inputSchema: {
540
+ browserId: BrowserAutomationBrowserIdSchema,
541
+ width: z.number().int().positive(),
542
+ height: z.number().int().positive(),
543
+ },
544
+ outputSchema: BrowserToolOutputSchema,
545
+ }, async ({ browserId, width, height }) => {
546
+ const context = resolveBrowserToolContext(options);
547
+ const payload = await options.broker.execute({
548
+ agentId: context.agentId,
549
+ cwd: context.cwd,
550
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {}),
551
+ command: {
552
+ command: "resize",
553
+ args: {
554
+ browserId,
555
+ width,
556
+ height,
557
+ },
558
+ },
559
+ });
560
+ return browserToolResult({ payload, context: { ...context, browserId } });
561
+ });
562
+ options.registerTool("browser_close_tab", {
563
+ title: "Close browser tab",
564
+ description: "Close a Paseo browser tab, remove its resident webview, and unregister it from the browser automation host. Use browserId from browser_new_tab or browser_list_tabs.",
565
+ inputSchema: {
566
+ browserId: BrowserAutomationBrowserIdSchema,
567
+ },
568
+ outputSchema: BrowserToolOutputSchema,
569
+ }, async ({ browserId }) => {
570
+ const context = resolveBrowserToolContext(options);
571
+ const payload = await options.broker.execute({
572
+ agentId: context.agentId,
573
+ cwd: context.cwd,
574
+ ...(context.workspaceId ? { workspaceId: context.workspaceId } : {}),
575
+ command: {
576
+ command: "close_tab",
577
+ args: {
578
+ browserId,
579
+ },
580
+ },
581
+ });
582
+ return browserToolResult({ payload, context: { ...context, browserId } });
583
+ });
464
584
  }
465
585
  function resolveBrowserToolContext(options) {
466
586
  const callerAgent = options.resolveCallerAgent();
@@ -518,15 +638,22 @@ function browserToolResult(params) {
518
638
  structuredContent: {
519
639
  ok: true,
520
640
  result: browserToolStructuredResult(payload.result),
641
+ ...(payload.dialogs ? { dialogs: payload.dialogs } : {}),
521
642
  context,
522
643
  },
523
644
  };
524
645
  }
525
646
  return {
526
- content: [{ type: "text", text: summarizeBrowserError(payload.error) }],
647
+ content: [
648
+ {
649
+ type: "text",
650
+ text: appendDialogSummary(summarizeBrowserError(payload.error), payload.dialogs),
651
+ },
652
+ ],
527
653
  structuredContent: {
528
654
  ok: false,
529
655
  error: payload.error,
656
+ ...(payload.dialogs ? { dialogs: payload.dialogs } : {}),
530
657
  context,
531
658
  },
532
659
  };
@@ -554,29 +681,30 @@ function browserToolImageContent(result) {
554
681
  };
555
682
  }
556
683
  function summarizeBrowserSuccess(payload) {
684
+ const withDialogs = (summary) => appendDialogSummary(summary, payload.dialogs);
557
685
  const controlSummary = summarizeBrowserControlSuccess(payload.result);
558
686
  if (controlSummary) {
559
- return controlSummary;
687
+ return withDialogs(controlSummary);
560
688
  }
561
689
  const refActionSummary = summarizeBrowserRefActionSuccess(payload.result);
562
690
  if (refActionSummary) {
563
- return refActionSummary;
691
+ return withDialogs(refActionSummary);
564
692
  }
565
693
  const diagnosticsSummary = summarizeBrowserDiagnosticsSuccess(payload.result);
566
694
  if (diagnosticsSummary) {
567
- return diagnosticsSummary;
695
+ return withDialogs(diagnosticsSummary);
568
696
  }
569
697
  const keyboardSummary = summarizeBrowserKeyboardSuccess(payload.result);
570
698
  if (keyboardSummary) {
571
- return keyboardSummary;
699
+ return withDialogs(keyboardSummary);
572
700
  }
573
701
  const navigationSummary = summarizeBrowserNavigationSuccess(payload.result);
574
702
  if (navigationSummary) {
575
- return navigationSummary;
703
+ return withDialogs(navigationSummary);
576
704
  }
577
705
  const mediaSummary = summarizeBrowserMediaSuccess(payload.result);
578
706
  if (mediaSummary) {
579
- return mediaSummary;
707
+ return withDialogs(mediaSummary);
580
708
  }
581
709
  if (payload.result.command === "list_tabs") {
582
710
  const count = payload.result.tabs.length;
@@ -587,22 +715,35 @@ function summarizeBrowserSuccess(payload) {
587
715
  const active = tab.isActive ? " active" : "";
588
716
  return `- browserId=${tab.browserId}${active} title=${JSON.stringify(tab.title || "Untitled")} url=${tab.url}`;
589
717
  });
590
- return [
718
+ return withDialogs([
591
719
  `Found ${count} Paseo browser tab${count === 1 ? "" : "s"}. Use these browserId values for tab-scoped browser tools.`,
592
720
  ...tabLines,
593
- ].join("\n");
721
+ ].join("\n"));
594
722
  }
595
723
  if (payload.result.command === "new_tab") {
596
- return `Created browser tab browserId=${payload.result.browserId} url=${payload.result.url}. Use this browserId for tab-scoped browser tools.`;
724
+ return withDialogs(`Created browser tab browserId=${payload.result.browserId} url=${payload.result.url}. Use this browserId for tab-scoped browser tools.`);
597
725
  }
598
726
  if (payload.result.command === "snapshot") {
599
- const count = payload.result.elements.length;
600
- return `Snapshot captured ${count} element${count === 1 ? "" : "s"}.`;
727
+ return withDialogs([
728
+ `Snapshot captured ${payload.result.stats.nodeCount} node${payload.result.stats.nodeCount === 1 ? "" : "s"} with ${payload.result.stats.refCount} ref${payload.result.stats.refCount === 1 ? "" : "s"}.`,
729
+ `Title: ${payload.result.title || "Untitled"}`,
730
+ `URL: ${payload.result.url}`,
731
+ "",
732
+ payload.result.snapshot,
733
+ ].join("\n"));
601
734
  }
602
735
  if (payload.result.command === "wait") {
603
- return `Browser wait matched ${payload.result.matched}.`;
736
+ return withDialogs(`Browser wait matched ${payload.result.matched}.`);
604
737
  }
605
- return `Browser ${payload.result.command} complete.`;
738
+ return withDialogs(`Browser ${payload.result.command} complete.`);
739
+ }
740
+ function appendDialogSummary(summary, dialogs) {
741
+ if (!dialogs || dialogs.length === 0) {
742
+ return summary;
743
+ }
744
+ return `${summary}\nHandled browser dialog${dialogs.length === 1 ? "" : "s"}: ${dialogs
745
+ .map((dialog) => `${dialog.action} ${dialog.type} ${JSON.stringify(dialog.message)}`)
746
+ .join("; ")}.`;
606
747
  }
607
748
  function summarizeBrowserMediaSuccess(result) {
608
749
  if (result.command === "screenshot") {
@@ -637,6 +778,13 @@ function summarizeBrowserNavigationSuccess(result) {
637
778
  return null;
638
779
  }
639
780
  function summarizeBrowserDiagnosticsSuccess(result) {
781
+ if (result.command === "evaluate") {
782
+ return [
783
+ "Browser evaluate returned:",
784
+ result.resultJson,
785
+ ...(result.truncated ? ["Result was truncated."] : []),
786
+ ].join("\n");
787
+ }
640
788
  if (result.command !== "logs") {
641
789
  return null;
642
790
  }
@@ -663,20 +811,31 @@ function summarizeBrowserControlSuccess(result) {
663
811
  if (result.command === "drag") {
664
812
  return `Dragged browser element ${result.sourceRef} to ${result.targetRef}.`;
665
813
  }
814
+ if (result.command === "scroll") {
815
+ return result.ref
816
+ ? `Scrolled browser element ${result.ref} by ${result.deltaX}, ${result.deltaY}.`
817
+ : `Scrolled browser by ${result.deltaX}, ${result.deltaY}.`;
818
+ }
819
+ if (result.command === "resize") {
820
+ return `Resized browser viewport to ${result.width}x${result.height}.`;
821
+ }
822
+ if (result.command === "close_tab") {
823
+ return `Closed browser tab ${result.browserId}.`;
824
+ }
666
825
  return null;
667
826
  }
668
827
  function summarizeBrowserError(error) {
669
828
  switch (error.code) {
670
829
  case "browser_disabled":
671
- return "Browser tools are disabled. Enable desktop browser tools on the host, then try again.";
672
- case "browser_no_desktop":
673
- return "No desktop browser automation client is connected. Open the Paseo desktop app and try again.";
830
+ return "Browser tools are disabled. Enable browser tools on the host, then try again.";
831
+ case "browser_no_host":
832
+ return error.message;
674
833
  case "browser_timeout":
675
- return "The browser did not respond before the timeout. Try again or check the desktop app.";
834
+ return "The browser did not respond before the timeout. Try again or check the browser host.";
676
835
  case "screenshot_no_frame":
677
836
  return error.message;
678
837
  case "browser_unsupported":
679
- return "This desktop build does not support that browser automation request yet.";
838
+ return error.message;
680
839
  case "browser_stale_ref":
681
840
  return "That browser element reference is stale. Take a new browser snapshot and try again.";
682
841
  default:
@@ -28,7 +28,7 @@ import { LoopService } from "./loop-service.js";
28
28
  import { ScheduleService } from "./schedule/service.js";
29
29
  import { type GitHubService } from "../services/github-service.js";
30
30
  import type { ProviderUsageService } from "../services/quota-fetcher/service.js";
31
- import { generateBranchNameFromFirstAgentContext } from "./worktree-branch-name-generator.js";
31
+ import { WorkspaceAutoName } from "./workspace-auto-name.js";
32
32
  export declare function resolveWaitForFinishError(options: {
33
33
  status: "permission" | "error" | "idle";
34
34
  final: AgentSnapshotPayload | null;
@@ -68,8 +68,8 @@ export interface SessionOptions {
68
68
  github?: GitHubService;
69
69
  createAgentMcpTransport?: AgentMcpTransportFactory;
70
70
  renameCurrentBranch?: typeof renameCurrentBranchDefault;
71
- generateWorkspaceName?: typeof generateBranchNameFromFirstAgentContext;
72
71
  workspaceGitService: WorkspaceGitService;
72
+ workspaceAutoName: WorkspaceAutoName;
73
73
  daemonConfigStore: DaemonConfigStore;
74
74
  mcpBaseUrl?: string | null;
75
75
  stt: Resolvable<SpeechToTextProvider | null>;
@@ -141,8 +141,8 @@ export declare class Session {
141
141
  private readonly filesystem;
142
142
  private readonly github;
143
143
  private readonly renameCurrentBranch;
144
- private readonly generateWorkspaceName;
145
144
  private readonly workspaceGitService;
145
+ private readonly workspaceAutoName;
146
146
  private readonly gitMutation;
147
147
  private readonly workspaceProvisioning;
148
148
  private readonly daemonConfigStore;
@@ -275,12 +275,6 @@ export declare class Session {
275
275
  private handleCancelAgentRequest;
276
276
  private handleAgentRewindRequest;
277
277
  private buildAgentSessionConfig;
278
- private scheduleAutoNameWorkspaceBranchForFirstAgent;
279
- private maybeAutoNameWorkspaceBranchForFirstAgent;
280
- private applyGeneratedWorkspaceTitle;
281
- private generateWorkspaceTitleFromContext;
282
- private maybeAutoNameDirectoryWorkspaceTitle;
283
- private scheduleAutoNameLocalWorkspaceTitleForFirstAgent;
284
278
  private isPathWithinRoot;
285
279
  /**
286
280
  * Handle clearing agent attention flag
@@ -355,7 +349,6 @@ export declare class Session {
355
349
  private registerWorkspaceForImportedAgent;
356
350
  private handleWorkspaceCreateRequest;
357
351
  private handleWorkspaceCreateLocal;
358
- private scheduleWorkspaceNaming;
359
352
  private handleWorkspaceCreateWorktree;
360
353
  private resolveWorktreeSourceCwd;
361
354
  private handleOpenProjectRequest;