Skip to content

Commit f9b254f

Browse files
committed
Merge remote-tracking branch 'origin/main' into feature/2122-editor-focus
# Conflicts: # src/core/prompts/sections/objective.ts
2 parents 0e03f5f + 19108f7 commit f9b254f

File tree

141 files changed

+3041
-427
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

141 files changed

+3041
-427
lines changed

.changeset/metal-suns-lay.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-code": patch
3+
---
4+
5+
Bug fix for trailing slash error when using LiteLLM provider
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# JSON File Writing Must Be Atomic
2+
3+
- MUST ALWAYS use `safeWriteJson(filePath: string, data: any): Promise<void>` from `src/utils/safeWriteJson.ts` instead of `JSON.stringify` with file-write operations
4+
- `safeWriteJson` prevents data corruption via atomic writes with locking and streams the write to minimize memory footprint
5+
- Test files are exempt from this rule

apps/web-evals/src/actions/runs.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,10 @@ export async function createRun({ suite, exercises = [], systemPrompt, ...values
5252

5353
const dockerArgs = [
5454
`--name evals-controller-${run.id}`,
55-
"--rm",
55+
// "--rm",
5656
"--network evals_default",
5757
"-v /var/run/docker.sock:/var/run/docker.sock",
58+
"-v /tmp/evals:/var/log/evals",
5859
"-e HOST_EXECUTION_METHOD=docker",
5960
]
6061

packages/cloud/src/AuthService.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type { CloudUserInfo } from "@roo-code/types"
99

1010
import { getClerkBaseUrl, getRooCodeApiUrl } from "./Config"
1111
import { RefreshTimer } from "./RefreshTimer"
12+
import { getUserAgent } from "./utils"
1213

1314
export interface AuthServiceEvents {
1415
"inactive-session": [data: { previousState: AuthState }]
@@ -435,7 +436,7 @@ export class AuthService extends EventEmitter<AuthServiceEvents> {
435436
}
436437

437438
private userAgent(): string {
438-
return `Roo-Code ${this.context.extension?.packageJSON?.version}`
439+
return getUserAgent(this.context)
439440
}
440441

441442
private static _instance: AuthService | null = null

packages/cloud/src/CloudService.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { CloudServiceCallbacks } from "./types"
77
import { AuthService } from "./AuthService"
88
import { SettingsService } from "./SettingsService"
99
import { TelemetryClient } from "./TelemetryClient"
10+
import { ShareService } from "./ShareService"
1011

1112
export class CloudService {
1213
private static _instance: CloudService | null = null
@@ -17,6 +18,7 @@ export class CloudService {
1718
private authService: AuthService | null = null
1819
private settingsService: SettingsService | null = null
1920
private telemetryClient: TelemetryClient | null = null
21+
private shareService: ShareService | null = null
2022
private isInitialized = false
2123
private log: (...args: unknown[]) => void
2224

@@ -48,6 +50,8 @@ export class CloudService {
4850

4951
this.telemetryClient = new TelemetryClient(this.authService, this.settingsService)
5052

53+
this.shareService = new ShareService(this.authService, this.settingsService, this.log)
54+
5155
try {
5256
TelemetryService.instance.register(this.telemetryClient)
5357
} catch (error) {
@@ -112,6 +116,18 @@ export class CloudService {
112116
this.telemetryClient!.capture(event)
113117
}
114118

119+
// ShareService
120+
121+
public async shareTask(taskId: string): Promise<boolean> {
122+
this.ensureInitialized()
123+
return this.shareService!.shareTask(taskId)
124+
}
125+
126+
public async canShareTask(): Promise<boolean> {
127+
this.ensureInitialized()
128+
return this.shareService!.canShareTask()
129+
}
130+
115131
// Lifecycle
116132

117133
public dispose(): void {
@@ -128,7 +144,13 @@ export class CloudService {
128144
}
129145

130146
private ensureInitialized(): void {
131-
if (!this.isInitialized || !this.authService || !this.settingsService || !this.telemetryClient) {
147+
if (
148+
!this.isInitialized ||
149+
!this.authService ||
150+
!this.settingsService ||
151+
!this.telemetryClient ||
152+
!this.shareService
153+
) {
132154
throw new Error("CloudService not initialized.")
133155
}
134156
}

packages/cloud/src/ShareService.ts

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import axios from "axios"
2+
import * as vscode from "vscode"
3+
4+
import { shareResponseSchema } from "@roo-code/types"
5+
import { getRooCodeApiUrl } from "./Config"
6+
import type { AuthService } from "./AuthService"
7+
import type { SettingsService } from "./SettingsService"
8+
import { getUserAgent } from "./utils"
9+
10+
export class ShareService {
11+
private authService: AuthService
12+
private settingsService: SettingsService
13+
private log: (...args: unknown[]) => void
14+
15+
constructor(authService: AuthService, settingsService: SettingsService, log?: (...args: unknown[]) => void) {
16+
this.authService = authService
17+
this.settingsService = settingsService
18+
this.log = log || console.log
19+
}
20+
21+
/**
22+
* Share a task: Create link and copy to clipboard
23+
* Returns true if successful, false if failed
24+
*/
25+
async shareTask(taskId: string): Promise<boolean> {
26+
try {
27+
const sessionToken = this.authService.getSessionToken()
28+
if (!sessionToken) {
29+
return false
30+
}
31+
32+
const response = await axios.post(
33+
`${getRooCodeApiUrl()}/api/extension/share`,
34+
{ taskId },
35+
{
36+
headers: {
37+
"Content-Type": "application/json",
38+
Authorization: `Bearer ${sessionToken}`,
39+
"User-Agent": getUserAgent(),
40+
},
41+
},
42+
)
43+
44+
const data = shareResponseSchema.parse(response.data)
45+
this.log("[share] Share link created successfully:", data)
46+
47+
if (data.success && data.shareUrl) {
48+
// Copy to clipboard
49+
await vscode.env.clipboard.writeText(data.shareUrl)
50+
return true
51+
} else {
52+
this.log("[share] Share failed:", data.error)
53+
return false
54+
}
55+
} catch (error) {
56+
this.log("[share] Error sharing task:", error)
57+
return false
58+
}
59+
}
60+
61+
/**
62+
* Check if sharing is available
63+
*/
64+
async canShareTask(): Promise<boolean> {
65+
try {
66+
if (!this.authService.isAuthenticated()) {
67+
return false
68+
}
69+
70+
return !!this.settingsService.getSettings()?.cloudSettings?.enableTaskSharing
71+
} catch (error) {
72+
this.log("[share] Error checking if task can be shared:", error)
73+
return false
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)