Skip to content

Commit 6a6084b

Browse files
committed
Toggle to switch browser size to 1280x800
1 parent eab4a80 commit 6a6084b

File tree

11 files changed

+62
-21
lines changed

11 files changed

+62
-21
lines changed

.changeset/dull-ravens-warn.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Add experimental option to use a bigger browser (1280x800)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ A fork of Cline, an autonomous coding agent, tweaked for more speed and flexibil
1010
- `.clinerules` for project-specific instructions
1111
- Drag and drop images into chats
1212
- Sound effects for feedback
13+
- Option to use a larger 1280x800 browser
1314
- Quick prompt copying from history
1415
- OpenRouter compression support
1516
- Support for newer Gemini models (gemini-exp-1206, gemini-2.0-flash-exp) and Meta 3, 3.1, and 3.2 models via AWS Bedrock

src/core/Cline.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,8 @@ export class Cline {
766766
throw new Error("MCP hub not available")
767767
}
768768

769-
const systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub, this.diffStrategy) + await addCustomInstructions(this.customInstructions ?? '', cwd)
769+
const { browserLargeViewport } = await this.providerRef.deref()?.getState() ?? {}
770+
const systemPrompt = await SYSTEM_PROMPT(cwd, this.api.getModel().info.supportsComputerUse ?? false, mcpHub, this.diffStrategy, browserLargeViewport) + await addCustomInstructions(this.customInstructions ?? '', cwd)
770771

771772
// If the previous API request's total token usage is close to the context window, truncate the conversation history to free up space for the new request
772773
if (previousApiReqIndex >= 0) {

src/core/prompts/system.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import { McpHub } from "../../services/mcp/McpHub"
99
export const SYSTEM_PROMPT = async (
1010
cwd: string,
1111
supportsComputerUse: boolean,
12-
mcpHub: McpHub,
13-
diffStrategy?: DiffStrategy
12+
mcpHub: McpHub,
13+
diffStrategy?: DiffStrategy,
14+
browserLargeViewport?: boolean
1415
) => `You are Cline, a highly skilled software engineer with extensive knowledge in many programming languages, frameworks, design patterns, and best practices.
1516
1617
====
@@ -111,7 +112,7 @@ Usage:
111112
Description: Request to interact with a Puppeteer-controlled browser. Every action, except \`close\`, will be responded to with a screenshot of the browser's current state, along with any new console logs. You may only perform one browser action per message, and wait for the user's response including a screenshot and logs to determine the next action.
112113
- The sequence of actions **must always start with** launching the browser at a URL, and **must always end with** closing the browser. If you need to visit a new URL that is not possible to navigate to from the current webpage, you must first close the browser, then launch again at the new URL.
113114
- While the browser is active, only the \`browser_action\` tool can be used. No other tools should be called during this time. You may proceed to use other tools only after closing the browser. For example if you run into an error and need to fix a file, you must close the browser, then use other tools to make the necessary changes, then re-launch the browser to verify the result.
114-
- The browser window has a resolution of **900x600** pixels. When performing any click actions, ensure the coordinates are within this resolution range.
115+
- The browser window has a resolution of **${browserLargeViewport ? "1280x800" : "900x600"}** pixels. When performing any click actions, ensure the coordinates are within this resolution range.
115116
- Before clicking on any elements such as icons, links, or buttons, you must consult the provided screenshot of the page to determine the coordinates of the element. The click should be targeted at the **center of the element**, not on its edges.
116117
Parameters:
117118
- action: (required) The action to perform. The available actions are:
@@ -129,7 +130,7 @@ Parameters:
129130
- Example: \`<action>close</action>\`
130131
- url: (optional) Use this for providing the URL for the \`launch\` action.
131132
* Example: <url>https://example.com</url>
132-
- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **900x600** resolution.
133+
- coordinate: (optional) The X and Y coordinates for the \`click\` action. Coordinates should be within the **${browserLargeViewport ? "1280x800" : "900x600"}** resolution.
133134
* Example: <coordinate>450,300</coordinate>
134135
- text: (optional) Use this for providing the text for the \`type\` action.
135136
* Example: <text>Hello, world!</text>

src/core/webview/ClineProvider.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ type GlobalStateKey =
6969
| "soundVolume"
7070
| "diffEnabled"
7171
| "alwaysAllowMcp"
72+
| "browserLargeViewport"
7273

7374
export const GlobalFileNames = {
7475
apiConversationHistory: "api_conversation_history.json",
@@ -584,8 +585,6 @@ export class ClineProvider implements vscode.WebviewViewProvider {
584585
}
585586
break
586587
}
587-
// Add more switch case statements here as more webview message commands
588-
// are created within the webview context (i.e. inside media/main.js)
589588
case "playSound":
590589
if (message.audioType) {
591590
const soundPath = path.join(this.context.extensionPath, "audio", `${message.audioType}.wav`)
@@ -609,6 +608,11 @@ export class ClineProvider implements vscode.WebviewViewProvider {
609608
await this.updateGlobalState("diffEnabled", diffEnabled)
610609
await this.postStateToWebview()
611610
break
611+
case "browserLargeViewport":
612+
const browserLargeViewport = message.bool ?? false
613+
await this.updateGlobalState("browserLargeViewport", browserLargeViewport)
614+
await this.postStateToWebview()
615+
break
612616
}
613617
},
614618
null,
@@ -937,6 +941,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
937941
diffEnabled,
938942
taskHistory,
939943
soundVolume,
944+
browserLargeViewport,
940945
} = await this.getState()
941946

942947
const allowedCommands = vscode.workspace
@@ -962,6 +967,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
962967
shouldShowAnnouncement: lastShownAnnouncementId !== this.latestAnnouncementId,
963968
allowedCommands,
964969
soundVolume: soundVolume ?? 0.5,
970+
browserLargeViewport: browserLargeViewport ?? false,
965971
}
966972
}
967973

@@ -1055,6 +1061,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
10551061
soundEnabled,
10561062
diffEnabled,
10571063
soundVolume,
1064+
browserLargeViewport,
10581065
] = await Promise.all([
10591066
this.getGlobalState("apiProvider") as Promise<ApiProvider | undefined>,
10601067
this.getGlobalState("apiModelId") as Promise<string | undefined>,
@@ -1093,6 +1100,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
10931100
this.getGlobalState("soundEnabled") as Promise<boolean | undefined>,
10941101
this.getGlobalState("diffEnabled") as Promise<boolean | undefined>,
10951102
this.getGlobalState("soundVolume") as Promise<number | undefined>,
1103+
this.getGlobalState("browserLargeViewport") as Promise<boolean | undefined>,
10961104
])
10971105

10981106
let apiProvider: ApiProvider
@@ -1149,6 +1157,7 @@ export class ClineProvider implements vscode.WebviewViewProvider {
11491157
soundEnabled: soundEnabled ?? false,
11501158
diffEnabled: diffEnabled ?? false,
11511159
soundVolume,
1160+
browserLargeViewport: browserLargeViewport ?? false,
11521161
}
11531162
}
11541163

src/services/browser/BrowserSession.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export class BrowserSession {
4545
return stats
4646
}
4747

48-
async launchBrowser() {
48+
async launchBrowser(): Promise<void> {
4949
console.log("launch browser called")
5050
if (this.browser) {
5151
// throw new Error("Browser already launched")
@@ -58,10 +58,9 @@ export class BrowserSession {
5858
"--user-agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
5959
],
6060
executablePath: stats.executablePath,
61-
defaultViewport: {
62-
width: 900,
63-
height: 600,
64-
},
61+
defaultViewport: await this.context.globalState.get("browserLargeViewport")
62+
? { width: 1280, height: 800 }
63+
: { width: 900, height: 600 },
6564
// headless: false,
6665
})
6766
// (latest version of puppeteer does not add headless to user agent)
@@ -245,25 +244,27 @@ export class BrowserSession {
245244
}
246245

247246
async scrollDown(): Promise<BrowserActionResult> {
247+
const isLargeViewport = await this.context.globalState.get("browserLargeViewport")
248248
return this.doAction(async (page) => {
249-
await page.evaluate(() => {
249+
await page.evaluate((scrollHeight) => {
250250
window.scrollBy({
251-
top: 600,
251+
top: scrollHeight,
252252
behavior: "auto",
253253
})
254-
})
254+
}, isLargeViewport ? 800 : 600)
255255
await delay(300)
256256
})
257257
}
258258

259259
async scrollUp(): Promise<BrowserActionResult> {
260+
const isLargeViewport = await this.context.globalState.get("browserLargeViewport")
260261
return this.doAction(async (page) => {
261-
await page.evaluate(() => {
262+
await page.evaluate((scrollHeight) => {
262263
window.scrollBy({
263-
top: -600,
264+
top: -scrollHeight,
264265
behavior: "auto",
265266
})
266-
})
267+
}, isLargeViewport ? 800 : 600)
267268
await delay(300)
268269
})
269270
}

src/shared/ExtensionMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ export interface ExtensionState {
5353
soundEnabled?: boolean
5454
soundVolume?: number
5555
diffEnabled?: boolean
56+
browserLargeViewport?: boolean
5657
}
5758

5859
export interface ClineMessage {

src/shared/WebviewMessage.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface WebviewMessage {
3434
| "soundEnabled"
3535
| "soundVolume"
3636
| "diffEnabled"
37+
| "browserLargeViewport"
3738
| "openMcpSettings"
3839
| "restartMcpServer"
3940
| "toggleToolAlwaysAllow"

webview-ui/src/components/chat/BrowserSessionRow.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import deepEqual from "fast-deep-equal"
22
import React, { memo, useEffect, useMemo, useRef, useState } from "react"
33
import { useSize } from "react-use"
4+
import { useExtensionState } from "../../context/ExtensionStateContext"
45
import {
56
BrowserAction,
67
BrowserActionResult,
@@ -219,6 +220,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
219220
}, [isBrowsing, currentPage?.nextAction?.messages])
220221

221222
// Use latest click position while browsing, otherwise use display state
223+
const { browserLargeViewport } = useExtensionState()
222224
const mousePosition = isBrowsing ? latestClickPosition || displayState.mousePosition : displayState.mousePosition
223225

224226
const [browserSessionRow, { height }] = useSize(
@@ -277,7 +279,7 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
277279
<div
278280
style={{
279281
width: "100%",
280-
paddingBottom: "calc(200%/3)",
282+
paddingBottom: browserLargeViewport ? "62.5%" : "66.67%", // 800/1280 = 0.625, 600/900 = 0.667
281283
position: "relative",
282284
backgroundColor: "var(--vscode-input-background)",
283285
}}>
@@ -319,8 +321,8 @@ const BrowserSessionRow = memo((props: BrowserSessionRowProps) => {
319321
<BrowserCursor
320322
style={{
321323
position: "absolute",
322-
top: `${(parseInt(mousePosition.split(",")[1]) / 600) * 100}%`,
323-
left: `${(parseInt(mousePosition.split(",")[0]) / 900) * 100}%`,
324+
top: `${(parseInt(mousePosition.split(",")[1]) / (browserLargeViewport ? 800 : 600)) * 100}%`,
325+
left: `${(parseInt(mousePosition.split(",")[0]) / (browserLargeViewport ? 1280 : 900)) * 100}%`,
324326
transition: "top 0.3s ease-out, left 0.3s ease-out",
325327
}}
326328
/>

webview-ui/src/components/settings/SettingsView.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
3333
setSoundVolume,
3434
diffEnabled,
3535
setDiffEnabled,
36+
browserLargeViewport = false,
37+
setBrowserLargeViewport,
3638
openRouterModels,
3739
setAllowedCommands,
3840
allowedCommands,
@@ -62,6 +64,7 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
6264
vscode.postMessage({ type: "soundEnabled", bool: soundEnabled })
6365
vscode.postMessage({ type: "soundVolume", value: soundVolume })
6466
vscode.postMessage({ type: "diffEnabled", bool: diffEnabled })
67+
vscode.postMessage({ type: "browserLargeViewport", bool: browserLargeViewport })
6568
onDone()
6669
}
6770
}
@@ -317,6 +320,20 @@ const SettingsView = ({ onDone }: SettingsViewProps) => {
317320
<div style={{ marginBottom: 5 }}>
318321
<h4 style={{ fontWeight: 500, marginBottom: 10 }}>Experimental Features</h4>
319322

323+
<div style={{ marginBottom: 10 }}>
324+
<VSCodeCheckbox checked={browserLargeViewport} onChange={(e: any) => setBrowserLargeViewport(e.target.checked)}>
325+
<span style={{ fontWeight: "500" }}>Use larger browser viewport (1280x800)</span>
326+
</VSCodeCheckbox>
327+
<p
328+
style={{
329+
fontSize: "12px",
330+
marginTop: "5px",
331+
color: "var(--vscode-descriptionForeground)",
332+
}}>
333+
When enabled, Cline will use a larger viewport size for browser interactions.
334+
</p>
335+
</div>
336+
320337
<div style={{ marginBottom: 5 }}>
321338
<div style={{ marginBottom: 10 }}>
322339
<VSCodeCheckbox checked={soundEnabled} onChange={(e: any) => setSoundEnabled(e.target.checked)}>

0 commit comments

Comments
 (0)