Skip to content

Commit 1a75855

Browse files
committed
Move @roo-code/cloud to the Roo-Code repo
1 parent 622da63 commit 1a75855

File tree

163 files changed

+8747
-647
lines changed

Some content is hidden

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

163 files changed

+8747
-647
lines changed

apps/web-roo-code/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
"embla-carousel-auto-scroll": "^8.6.0",
2323
"embla-carousel-autoplay": "^8.6.0",
2424
"embla-carousel-react": "^8.6.0",
25-
"framer-motion": "^12.15.0",
25+
"framer-motion": "12.15.0",
2626
"lucide-react": "^0.518.0",
2727
"next": "^15.2.5",
2828
"next-themes": "^0.4.6",

package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,7 @@
2424
"knip": "knip --include files",
2525
"update-contributors": "node scripts/update-contributors.js",
2626
"evals": "dotenvx run -f packages/evals/.env.development packages/evals/.env.local -- docker compose -f packages/evals/docker-compose.yml --profile server --profile runner up --build --scale runner=0",
27-
"npm:publish:types": "pnpm --filter @roo-code/types npm:publish",
28-
"link-workspace-packages": "tsx scripts/link-packages.ts",
29-
"unlink-workspace-packages": "tsx scripts/link-packages.ts --unlink"
27+
"npm:publish:types": "pnpm --filter @roo-code/types npm:publish"
3028
},
3129
"devDependencies": {
3230
"@changesets/cli": "^2.27.10",
@@ -47,7 +45,7 @@
4745
"prettier": "^3.4.2",
4846
"rimraf": "^6.0.1",
4947
"tsx": "^4.19.3",
50-
"turbo": "^2.5.3",
48+
"turbo": "^2.5.6",
5149
"typescript": "^5.4.5"
5250
},
5351
"lint-staged": {

packages/cloud/eslint.config.mjs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { config } from "@roo-code/config-eslint/base"
2+
import globals from "globals"
3+
4+
/** @type {import("eslint").Linter.Config} */
5+
export default [
6+
...config,
7+
{
8+
files: ["**/*.cjs"],
9+
languageOptions: {
10+
globals: {
11+
...globals.node,
12+
...globals.commonjs,
13+
},
14+
sourceType: "commonjs",
15+
},
16+
rules: {
17+
"@typescript-eslint/no-require-imports": "off",
18+
},
19+
},
20+
]

packages/cloud/package.json

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"name": "@roo-code/cloud",
3+
"description": "Roo Code Cloud services.",
4+
"version": "0.0.0",
5+
"type": "module",
6+
"exports": "./src/index.ts",
7+
"scripts": {
8+
"lint": "eslint src --ext=ts --max-warnings=0",
9+
"check-types": "tsc --noEmit",
10+
"test": "vitest run",
11+
"clean": "rimraf .turbo"
12+
},
13+
"dependencies": {
14+
"@roo-code/types": "workspace:^",
15+
"ioredis": "^5.6.1",
16+
"jwt-decode": "^4.0.0",
17+
"p-wait-for": "^5.0.2",
18+
"socket.io-client": "^4.8.1",
19+
"zod": "^3.25.76"
20+
},
21+
"devDependencies": {
22+
"@roo-code/config-eslint": "workspace:^",
23+
"@roo-code/config-typescript": "workspace:^",
24+
"@types/node": "^24.1.0",
25+
"@types/vscode": "^1.102.0",
26+
"globals": "^16.3.0",
27+
"vitest": "^3.2.4"
28+
}
29+
}

packages/cloud/src/CloudAPI.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import { z } from "zod"
2+
3+
import { type AuthService, type ShareVisibility, type ShareResponse, shareResponseSchema } from "@roo-code/types"
4+
5+
import { getRooCodeApiUrl } from "./config.js"
6+
import { getUserAgent } from "./utils.js"
7+
import { AuthenticationError, CloudAPIError, NetworkError, TaskNotFoundError } from "./errors.js"
8+
9+
interface CloudAPIRequestOptions extends Omit<RequestInit, "headers"> {
10+
timeout?: number
11+
headers?: Record<string, string>
12+
}
13+
14+
export class CloudAPI {
15+
private authService: AuthService
16+
private log: (...args: unknown[]) => void
17+
private baseUrl: string
18+
19+
constructor(authService: AuthService, log?: (...args: unknown[]) => void) {
20+
this.authService = authService
21+
this.log = log || console.log
22+
this.baseUrl = getRooCodeApiUrl()
23+
}
24+
25+
private async request<T>(
26+
endpoint: string,
27+
options: CloudAPIRequestOptions & {
28+
parseResponse?: (data: unknown) => T
29+
} = {},
30+
): Promise<T> {
31+
const { timeout = 30_000, parseResponse, headers = {}, ...fetchOptions } = options
32+
33+
const sessionToken = this.authService.getSessionToken()
34+
35+
if (!sessionToken) {
36+
throw new AuthenticationError()
37+
}
38+
39+
const url = `${this.baseUrl}${endpoint}`
40+
41+
const requestHeaders = {
42+
"Content-Type": "application/json",
43+
Authorization: `Bearer ${sessionToken}`,
44+
"User-Agent": getUserAgent(),
45+
...headers,
46+
}
47+
48+
try {
49+
const response = await fetch(url, {
50+
...fetchOptions,
51+
headers: requestHeaders,
52+
signal: AbortSignal.timeout(timeout),
53+
})
54+
55+
if (!response.ok) {
56+
await this.handleErrorResponse(response, endpoint)
57+
}
58+
59+
const data = await response.json()
60+
61+
if (parseResponse) {
62+
return parseResponse(data)
63+
}
64+
65+
return data as T
66+
} catch (error) {
67+
if (error instanceof TypeError && error.message.includes("fetch")) {
68+
throw new NetworkError(`Network error while calling ${endpoint}`)
69+
}
70+
71+
if (error instanceof CloudAPIError) {
72+
throw error
73+
}
74+
75+
if (error instanceof Error && error.name === "AbortError") {
76+
throw new CloudAPIError(`Request to ${endpoint} timed out`, undefined, undefined)
77+
}
78+
79+
throw new CloudAPIError(
80+
`Unexpected error while calling ${endpoint}: ${error instanceof Error ? error.message : String(error)}`,
81+
)
82+
}
83+
}
84+
85+
private async handleErrorResponse(response: Response, endpoint: string): Promise<never> {
86+
let responseBody: unknown
87+
88+
try {
89+
responseBody = await response.json()
90+
} catch {
91+
responseBody = await response.text()
92+
}
93+
94+
switch (response.status) {
95+
case 401:
96+
throw new AuthenticationError()
97+
case 404:
98+
if (endpoint.includes("/share")) {
99+
throw new TaskNotFoundError()
100+
}
101+
throw new CloudAPIError(`Resource not found: ${endpoint}`, 404, responseBody)
102+
default:
103+
throw new CloudAPIError(
104+
`HTTP ${response.status}: ${response.statusText}`,
105+
response.status,
106+
responseBody,
107+
)
108+
}
109+
}
110+
111+
async shareTask(taskId: string, visibility: ShareVisibility = "organization"): Promise<ShareResponse> {
112+
this.log(`[CloudAPI] Sharing task ${taskId} with visibility: ${visibility}`)
113+
114+
const response = await this.request("/api/extension/share", {
115+
method: "POST",
116+
body: JSON.stringify({ taskId, visibility }),
117+
parseResponse: (data) => shareResponseSchema.parse(data),
118+
})
119+
120+
this.log("[CloudAPI] Share response:", response)
121+
return response
122+
}
123+
124+
async bridgeConfig() {
125+
return this.request("/api/extension/bridge/config", {
126+
method: "GET",
127+
parseResponse: (data) =>
128+
z
129+
.object({
130+
userId: z.string(),
131+
socketBridgeUrl: z.string(),
132+
token: z.string(),
133+
})
134+
.parse(data),
135+
})
136+
}
137+
}

0 commit comments

Comments
 (0)