Skip to content

Conversation

@caffeinum
Copy link
Contributor

@caffeinum caffeinum commented Nov 29, 2025

Summary

  • Add cloud workspace button (blue cloud icon) in header next to the regular "+" button
  • Creates E2B sandbox via yolocode API and opens two embedded webview tabs:
    • Cloud Agent - Claude chat UI at port 7030
    • Cloud Terminal - WebSSH terminal at port 8888 (pre-filled with localhost/user credentials)
  • Uses electron <webview> tag instead of iframe to properly embed external URLs
  • Cloud sandbox status shown on workspace tabs (blue cloud icon = running, yellow warning = stopped)
  • Dangling sandboxes (running but not linked to a workspace) shown in tab bar for management

Architecture

  • Cloud tabs: Dedicated TabType.Cloud with createCloudTab() factory that extracts sandbox ID from URL for tab naming
  • tRPC: All cloud operations migrated to tRPC router (cloud.createSandbox, cloud.deleteSandbox, cloud.listSandboxes, etc.)
  • Status polling: Each WorkspaceItem fetches its own cloud status via getWorktreeCloudStatus query (30s polling)
  • Sandbox linking: Sandboxes stored on worktree in local db, auto-deleted when workspace is deleted
  • Split tabs: Cloud tabs fully support split view - can be split via context menu, keyboard shortcuts, or drag-and-drop

Auth

Currently uses user's GitHub token (gh auth token) which is sent to yolocode API. Users will need to authenticate with yolocode directly instead.

Setup

Requires CLAUDE_CODE_OAUTH_TOKEN in .env file. Get it by running:

claude setup-token

TODO

  • Draft implementation for cloud worktrees using yolocode.ai
  • Show content of AI chat and cloud terminal from yolocode sandbox
  • Cloud status indicators on workspace tabs
  • Dangling sandbox management
  • Migrate IPC handlers to tRPC
  • Split tabs support for Cloud tabs
  • Proper yolocode auth (not GitHub token)

…ation

- add CloudSandbox type and cloudSandbox field to Worktree
- create cloud-api-client.ts for yolocode E2B sandbox API (uses gh token auth)
- add cloud-sandbox-create and cloud-sandbox-delete IPC channels
- add New Cloud Terminal button in TabsView with blue styling
- extract github repo URL from local repo path using git remote
- add WebView tab type with url field
- create WebView component (iframe wrapper)
- create WebViewTabView to render webview tabs
- update tab store to support url and title options
- add 'New Cloud Agent' button (claude chat UI at port 7030)
- add 'New Cloud Terminal' button (webssh at port 8888)
- both open as embedded iframe tabs instead of browser windows
- add CloudWorkspaceButton component with blue cloud icon
- creates workspace with two webview tabs: Cloud Agent (7030) + Cloud Terminal (8888)
- remove cloud buttons from TabsView sidebar (now in header)
- cloud workspaces are created via dropdown menu like regular workspaces
… URLs

iframe was blocked by electron security. webview tag is the proper way
to embed external content in electron apps.
adds ?hostname=localhost&username=user to webssh URL so user doesn't
have to manually enter connection details for the e2b sandbox
@vercel
Copy link

vercel bot commented Nov 29, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
website Error Error Dec 9, 2025 6:19am

@coderabbitai
Copy link

coderabbitai bot commented Nov 29, 2025

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This PR adds cloud sandbox creation and management to the desktop app. It introduces a CloudApiClient for cloud API interaction, IPC handlers for sandbox operations, new WebView tab support for embedded web content, and UI components for creating and managing cloud workspaces with integrated terminal and agent interfaces.

Changes

Cohort / File(s) Summary
Backend Cloud API Client
apps/desktop/src/main/lib/cloud-api-client.ts
New CloudApiClient class that fetches GitHub auth tokens via gh CLI, creates/deletes cloud sandboxes via HTTP requests, handles token credentialing, masks sensitive data in logs, and maps API responses to CloudSandbox objects with port 7030 for web UI. Exports singleton instance.
Main Process Cloud Setup
apps/desktop/src/main/index.ts, apps/desktop/src/main/lib/cloud-ipcs.ts
Registers cloud IPC handlers during app startup. Implements two handlers: cloud-sandbox-create validates project existence and derives GitHub URL from mainRepoPath before delegating to CloudApiClient; cloud-sandbox-delete delegates to CloudApiClient. Helper function infers GitHub HTTPS URLs from local git repository origins.
IPC Channel & Type Definitions
apps/desktop/src/shared/ipc-channels/worktree.ts, apps/desktop/src/shared/types.ts
Defines CloudSandbox interface with id, name, status, optional websshHost/claudeHost, createdAt, and error fields. Adds cloud-sandbox-create and cloud-sandbox-delete IPC channels. Extends Worktree with optional cloudSandbox property.
Tab System Enhancements
apps/desktop/src/renderer/stores/tabs/types.ts, apps/desktop/src/renderer/stores/tabs/utils.ts, apps/desktop/src/renderer/stores/tabs/store.ts, apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
Adds WebView to TabType enum. Introduces WebViewTab interface and CreateTabOptions type. Extends tab creation pipeline (addTab, handleAddTab, createNewTab) to accept optional options parameter with url and title. Generates "Cloud Terminal" title for WebView tabs; enforces URL requirement for WebView tab creation.
WebView Components
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts, apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
New WebView component renders Electron webview element with dom-ready and did-fail-load listeners, handles cleanup on unmount. WebViewTabView wraps WebView for tab rendering. Includes barrel export in index.ts.
Tab Rendering & UI Updates
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx, apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx, apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx, apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
Adds conditional rendering for WebView tabs in TabsContent. New CloudWorkspaceButton component with dropdown UI for creating cloud workspaces; manages workspace/sandbox creation flow, project selection, and error handling with toast notifications. Updates TopBar to render CloudWorkspaceButton. Minor spacing change in TabsView from justify-between to gap-2.

Sequence Diagram

sequenceDiagram
    participant User
    participant CloudWorkspaceButton as CloudWorkspaceButton<br/>(Renderer)
    participant TabsStore as TabsStore<br/>(Renderer)
    participant IPC as IPC Channel
    participant CloudHandlers as Cloud Handlers<br/>(Main Process)
    participant CloudApiClient as CloudApiClient<br/>(Main Process)
    participant CloudAPI as Cloud API<br/>(External)
    participant GitHub as GitHub CLI

    User->>CloudWorkspaceButton: Click "Create Cloud Workspace"
    CloudWorkspaceButton->>TabsStore: addTab(workspaceId, TabType.Single)
    TabsStore-->>CloudWorkspaceButton: workspace created
    
    CloudWorkspaceButton->>CloudWorkspaceButton: Derive GitHub repo URL<br/>from project
    
    CloudWorkspaceButton->>IPC: send "cloud-sandbox-create"<br/>{name, projectId, taskDescription}
    
    IPC->>CloudHandlers: Handle cloud-sandbox-create
    CloudHandlers->>CloudHandlers: Validate project exists<br/>Get mainRepoPath
    CloudHandlers->>CloudHandlers: Infer GitHub HTTPS URL<br/>from git origin
    
    CloudHandlers->>CloudApiClient: createSandbox(params)
    CloudApiClient->>GitHub: gh auth token (via CLI)
    GitHub-->>CloudApiClient: auth token
    
    CloudApiClient->>CloudAPI: POST /sandbox<br/>(auth token, repo, env vars)
    CloudAPI-->>CloudApiClient: CloudSandbox object
    
    CloudHandlers-->>IPC: response {success, sandbox}
    IPC-->>CloudWorkspaceButton: sandbox created
    
    CloudWorkspaceButton->>TabsStore: addTab(workspaceId,<br/>TabType.WebView, {url: agentURL})
    TabsStore-->>CloudWorkspaceButton: Cloud Agent tab created
    
    CloudWorkspaceButton->>TabsStore: addTab(workspaceId,<br/>TabType.WebView, {url: terminalURL})
    TabsStore-->>CloudWorkspaceButton: Cloud Terminal tab created
    
    CloudWorkspaceButton-->>User: Workspace ready with<br/>Cloud Agent & Terminal
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • CloudApiClient logic: GitHub token fetching via CLI, request building with sensitive data masking, error handling, and response mapping deserve careful review
  • IPC handler validation: Project existence checks and GitHub URL inference from git origins require verification
  • Tab system integration: Multiple files changed in coordinated fashion (types, utils, store, helpers)—verify options flow correctly through the entire pipeline
  • WebView component: Event listener attachment/cleanup and webview attribute typing (TS-expect-error bypass)
  • CloudWorkspaceButton orchestration: Complex UI state management for async operations, workspace creation, sandbox creation, and webview tab setup

Possibly related PRs

  • tabs interaction #111: Modifies the tabs subsystem (types, utils, store, tab-crud) with overlapping changes to addTab/createNewTab signatures and tab creation logic.
  • tabs mangement interaction #105: Updates renderer's tab/workspace subsystem (store, types, utils, UI components), including new tab type handling and tab-creation APIs.
  • initial ws #77: Extends the WorktreeChannels IPC contract with new cloud-related channels, directly building on the IPC definitions introduced in this PR.

Poem

🐰 A sandbox in the cloud, so high and free,
Webviews dance where terminals be,
GitHub tokens whisper, handlers align,
Cloud workspaces bloom—what a design! ☁️
The tabs now flutter with WebView delight,
Our desktop app shines so bright!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: adding cloud workspaces via yolocode.ai integration to the desktop app.
Description check ✅ Passed PR description is comprehensive with clear summary, architecture, setup, and TODO tracking but lacks some template sections.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@caffeinum caffeinum marked this pull request as draft November 29, 2025 01:27
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (7)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx (2)

59-118: Cloud sandbox creation flow is solid, but consider routing IPC through tRPC

The overall flow (create workspace → invoke cloud-sandbox-create → open WebView tabs → toast success/failure) is clean and well-guarded with isCreating and error handling. However, per the desktop guidelines, Electron IPC should go through the tRPC layer rather than calling window.ipcRenderer.invoke directly. It would be preferable to expose a cloudSandbox.create procedure in src/lib/trpc and call that here so IPC contracts remain centralized and typed in one place.


148-188: Recent projects list UI looks good; consider avoiding inline project typing

The recent-projects dropdown rendering and disabled states are wired correctly. To avoid potential drift from the backend type, you might want to derive the project shape from trpc.projects.getRecents’s inferred output type instead of repeating { id; name; mainRepoPath } inline, but that’s purely a nicety.

apps/desktop/src/renderer/stores/tabs/types.ts (1)

6-7: WebView tab typing aligns with creation logic; consider reusing CreateTabOptions

Adding TabType.WebView, WebViewTab, and extending the Tab union all look consistent with the createNewTab implementation and the new WebView UI. To keep things DRY, you could reuse the CreateTabOptions type here instead of redefining { url?: string; title?: string } in the addTab signature.

Please also verify that all places switching on tab.type now handle TabType.WebView to avoid unhandled variants at runtime.

Also applies to: 22-25, 32-32, 41-45

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1)

15-20: Consider toning down logging and revisiting allowpopups

The console.log/console.error calls on every webview load/failure may be a bit noisy in production; consider routing through whatever logging/debug mechanism you use elsewhere or gating behind a dev flag. Also, allowpopups="true" broadens what the embedded content can do—please double-check that you really need popups enabled for these cloud views.

Also applies to: 33-39

apps/desktop/src/main/lib/cloud-api-client.ts (3)

37-53: Synchronous gh auth token can block the main thread; consider caching or async

Using execSync("gh auth token") on each createSandbox/deleteSandbox call will block the Electron main process while the CLI runs, which can momentarily freeze the UI. Caching the token for the app lifetime or switching to an async child_process call (or direct config file read) would reduce this impact.


37-38: Hard-coded staging URL and missing timeouts make the client environment-sensitive

The client is currently pinned to https://staging.yolocode.ai/api/e2b-sandboxes, and the fetch calls don’t use any timeout/abort handling. Before shipping broadly, it’d be safer to drive baseUrl via configuration (env or build-time flag) and add a simple timeout (e.g., AbortController) so a hung network call doesn’t indefinitely block IPC responses.

Also applies to: 69-85, 97-115, 158-171


117-132: CloudSandbox mapping is straightforward; status and claudeHost rewrite are assumptions

The mapping from CreateSandboxResponse to CloudSandbox is clear, but it hardcodes status: "running" and rewrites claudeHost to port 7030 regardless of what the API returns. If the backend ever reports more nuanced statuses or changes its port scheme, you may want to derive status from data.status and make the port rewrite conditional or driven by config.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4ae2cd and 910f825.

📒 Files selected for processing (16)
  • apps/desktop/src/main/index.ts (2 hunks)
  • apps/desktop/src/main/lib/cloud-api-client.ts (1 hunks)
  • apps/desktop/src/main/lib/cloud-ipcs.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx (1 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (2 hunks)
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx (1 hunks)
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1 hunks)
  • apps/desktop/src/renderer/stores/tabs/store.ts (1 hunks)
  • apps/desktop/src/renderer/stores/tabs/types.ts (3 hunks)
  • apps/desktop/src/renderer/stores/tabs/utils.ts (4 hunks)
  • apps/desktop/src/shared/ipc-channels/worktree.ts (2 hunks)
  • apps/desktop/src/shared/types.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
apps/desktop/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

For Electron interprocess communication, ALWAYS use tRPC as defined in src/lib/trpc

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/worktree.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-api-client.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/main/lib/cloud-ipcs.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/shared/types.ts
  • apps/desktop/src/renderer/stores/tabs/store.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/renderer/stores/tabs/utils.ts
apps/desktop/**/*.{ts,tsx}

📄 CodeRabbit inference engine (apps/desktop/AGENTS.md)

apps/desktop/**/*.{ts,tsx}: Please use alias as defined in tsconfig.json when possible
Prefer zustand for state management if it makes sense. Do not use effect unless absolutely necessary

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/worktree.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-api-client.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/main/lib/cloud-ipcs.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/shared/types.ts
  • apps/desktop/src/renderer/stores/tabs/store.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/renderer/stores/tabs/utils.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx}: Avoid using any type - use explicit types instead for type safety
Use camelCase for variable and function names following existing codebase patterns
Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications
Follow existing patterns and match the codebase style when writing new code

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/shared/ipc-channels/worktree.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-api-client.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/main/lib/cloud-ipcs.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/shared/types.ts
  • apps/desktop/src/renderer/stores/tabs/store.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/renderer/stores/tabs/utils.ts
**/components/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

**/components/**/*.tsx: Create one folder per component with structure: ComponentName/ComponentName.tsx + index.ts for barrel export
Co-locate tests next to the component file they test (e.g., ComponentName.test.tsx)
Co-locate dependencies (utils, hooks, constants, config, stories) next to the file using them
Use nested components/ subdirectory within a parent component only if a sub-component is used 2+ times within that parent; otherwise keep it in the parent's components/ folder
One component per file - avoid multi-component files

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
apps/desktop/src/renderer/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/stores/tabs/types.ts
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/stores/tabs/store.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
  • apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts
  • apps/desktop/src/renderer/stores/tabs/utils.ts
apps/desktop/src/renderer/**/*.tsx

📄 CodeRabbit inference engine (AGENTS.md)

Call IPC methods using window.ipcRenderer.invoke() with object parameters - TypeScript will infer the exact response type automatically

Files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx
  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
apps/desktop/src/main/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

Node.js modules (fs, path, os, net, etc.) can be used in main process code only

Files:

  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-api-client.ts
  • apps/desktop/src/main/lib/cloud-ipcs.ts
apps/desktop/src/main/index.ts

📄 CodeRabbit inference engine (AGENTS.md)

Load .env file with override: true at the start of the main process before any imports

Files:

  • apps/desktop/src/main/index.ts
apps/desktop/src/main/lib/*-ipcs.ts

📄 CodeRabbit inference engine (AGENTS.md)

IPC handlers must accept a single object parameter, not positional parameters, to match type-safe renderer calls

Files:

  • apps/desktop/src/main/lib/cloud-ipcs.ts
🧠 Learnings (10)
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx} : Please use alias as defined in `tsconfig.json` when possible

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/shared/ipc-channels.ts : Define all IPC channel types with request and response interfaces before implementing handlers

Applied to files:

  • apps/desktop/src/shared/ipc-channels/worktree.ts
  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-ipcs.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/main/**/*.{ts,tsx} : Node.js modules (fs, path, os, net, etc.) can be used in main process code only

Applied to files:

  • apps/desktop/src/main/index.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/main/lib/*-ipcs.ts : IPC handlers must accept a single object parameter, not positional parameters, to match type-safe renderer calls

Applied to files:

  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-ipcs.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/renderer/**/*.{ts,tsx} : Never import Node.js modules (fs, path, os, net, etc.) in renderer process code - browser environment only

Applied to files:

  • apps/desktop/src/main/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/lib/**/*.ts : Never import Node.js modules in shared code like `src/lib/electron-router-dom.ts` - this code runs in both main and renderer processes

Applied to files:

  • apps/desktop/src/main/index.ts
📚 Learning: 2025-11-24T21:33:13.244Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: apps/desktop/AGENTS.md:0-0
Timestamp: 2025-11-24T21:33:13.244Z
Learning: Applies to apps/desktop/**/*.{ts,tsx,js,jsx} : For Electron interprocess communication, ALWAYS use tRPC as defined in `src/lib/trpc`

Applied to files:

  • apps/desktop/src/main/index.ts
  • apps/desktop/src/main/lib/cloud-ipcs.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to apps/desktop/src/renderer/**/*.tsx : Call IPC methods using `window.ipcRenderer.invoke()` with object parameters - TypeScript will infer the exact response type automatically

Applied to files:

  • apps/desktop/src/main/lib/cloud-ipcs.ts
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to **/*.{ts,tsx} : Keep diffs minimal with targeted edits only - avoid unnecessary changes when making modifications

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx
  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
📚 Learning: 2025-11-28T01:03:47.951Z
Learnt from: CR
Repo: superset-sh/superset PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-11-28T01:03:47.951Z
Learning: Applies to packages/ui/src/**/*.tsx : Use shadcn/ui components and TailwindCSS v4 for all UI component styling in the shared UI package

Applied to files:

  • apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx
🧬 Code graph analysis (13)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx (5)
apps/desktop/src/renderer/stores/tabs/hooks.ts (1)
  • useAddTab (7-7)
packages/ui/src/components/sonner.tsx (1)
  • toast (30-30)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
packages/ui/src/components/dropdown-menu.tsx (3)
  • DropdownMenu (245-245)
  • DropdownMenuTrigger (247-247)
  • DropdownMenuContent (248-248)
packages/ui/src/components/button.tsx (1)
  • Button (61-61)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx (3)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
  • WebViewTab (22-25)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1)
  • WebView (7-42)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts (1)
  • WebView (1-1)
apps/desktop/src/renderer/stores/tabs/types.ts (2)
apps/desktop/src/shared/types.ts (3)
  • TabType (23-30)
  • MosaicNode (35-35)
  • Tab (44-56)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1)
  • WebView (7-42)
apps/desktop/src/shared/ipc-channels/worktree.ts (1)
apps/desktop/src/shared/types.ts (1)
  • CloudSandbox (59-67)
apps/desktop/src/main/index.ts (1)
apps/desktop/src/main/lib/cloud-ipcs.ts (1)
  • registerCloudHandlers (41-81)
apps/desktop/src/main/lib/cloud-api-client.ts (1)
apps/desktop/src/shared/types.ts (1)
  • CloudSandbox (59-67)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx (1)
apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx (1)
  • CloudWorkspaceButton (19-193)
apps/desktop/src/main/lib/cloud-ipcs.ts (1)
apps/desktop/src/main/lib/cloud-api-client.ts (1)
  • cloudApiClient (184-184)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (2)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx (1)
  • WebViewTabView (8-14)
apps/desktop/src/renderer/stores/tabs/store.ts (2)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1)
  • handleAddTab (6-33)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts (1)
  • WebView (1-1)
apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (3)
apps/desktop/src/renderer/stores/tabs/types.ts (1)
  • TabsState (34-38)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/stores/tabs/utils.ts (2)
  • CreateTabOptions (11-14)
  • createNewTab (16-74)
apps/desktop/src/renderer/stores/tabs/utils.ts (3)
apps/desktop/src/shared/types.ts (1)
  • TabType (23-30)
apps/desktop/src/renderer/stores/tabs/types.ts (2)
  • Tab (32-32)
  • WebViewTab (22-25)
apps/desktop/src/renderer/stores/tabs/utils/terminal-naming.ts (1)
  • generateTerminalName (41-46)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Build
🔇 Additional comments (13)
apps/desktop/src/renderer/screens/main/components/WorkspaceView/Sidebar/TabsView/index.tsx (1)

43-43: LGTM! Better button layout.

The change from justify-between to gap-2 improves the button layout by grouping the icon and text together rather than spreading them to opposite ends. This creates a more cohesive and conventional appearance for an icon+text button.

apps/desktop/src/main/index.ts (1)

5-5: Cloud IPC handler registration placement looks good

Registering registerCloudHandlers() alongside registerStorageHandlers() keeps IPC setup centralized and happens early in main startup, which is consistent with the existing pattern. No issues from this wiring alone.

Also applies to: 32-32

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/index.tsx (1)

5-5: CloudWorkspaceButton integration into the top bar looks consistent

Importing and rendering <CloudWorkspaceButton className="no-drag" /> next to WorkspaceDropdown matches existing layout patterns and preserves the draggable area semantics via no-drag. No functional or guideline issues here.

Also applies to: 127-129

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/index.ts (1)

1-1: Barrel export for WebView matches component structure guidelines

export { WebView } from "./WebView"; is a clean barrel that fits the co-location/one-component-per-folder pattern and simplifies imports (e.g. ./WebView).

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebViewTabView.tsx (1)

1-14: WebViewTabView correctly wraps WebView for WebViewTab

Typing tab as WebViewTab and passing tab.url into <WebView /> is straightforward and type-safe; the full-size container with overflow-hidden and bg-background is appropriate for embedding the webview. Looks good as-is.

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/index.tsx (1)

9-9: WebViewTabView integration into TabsContent is consistent with existing tab routing

The new TabType.WebView branch cleanly mirrors the existing Single/Group handling, and passing tabToRender into WebViewTabView matches the WebViewTab discriminated type pattern. As long as TabType and the Tab union define the WebView variant (which they do elsewhere in this PR), this is solid.

Also applies to: 49-51

apps/desktop/src/renderer/stores/tabs/store.ts (1)

43-47: addTab options propagation looks correct

Extending addTab to accept an options argument and threading it through to handleAddTab(state, workspaceId, type, options) cleanly exposes the new CreateTabOptions without breaking existing callers (it’s optional and has a default type). Just ensure the TabsStore interface in ./types reflects the updated addTab signature so TS catches any misuse.

apps/desktop/src/renderer/stores/tabs/utils.ts (1)

1-1: New CreateTabOptions and WebView tab handling are coherent and enforce good invariants

The CreateTabOptions shape and the updated createNewTab logic look solid:

  • Title selection respects an explicit options.title, falls back to the existing terminal naming for TabType.Single, uses "Cloud Terminal" for bare WebView tabs, and keeps "New Split View" for others.
  • The WebView branch requiring options.url and throwing otherwise is a good early guard, and returning a WebViewTab keeps the union discriminant intact.

This meshes well with the cloud workspace flow where you provide both url and an explicit title from the caller.

Also applies to: 11-14, 20-21, 31-40, 56-65

apps/desktop/src/shared/types.ts (1)

79-79: Adding cloudSandbox to Worktree: verify serialization and migration paths

The new optional cloudSandbox?: CloudSandbox property on Worktree is fine type‑wise, but please double‑check that any persistence layer (JSON config, DB, IPC payloads) correctly tolerates this new field for both old and new data without breaking loading or validation.

apps/desktop/src/renderer/screens/main/components/TopBar/WorkspaceTabs/CloudWorkspaceButton.tsx (1)

28-57: Sandbox name generator is simple and effective

The adjective–noun–timestamp scheme is deterministic enough for uniqueness and user-friendly identification; no issues from my side here.

apps/desktop/src/renderer/stores/tabs/helpers/tab-crud.ts (1)

3-13: Options plumbed through handleAddTab correctly

Extending handleAddTab with options?: CreateTabOptions and forwarding it to createNewTab is clean and backward compatible with existing callers that don’t pass options.

apps/desktop/src/shared/ipc-channels/worktree.ts (1)

5-5: Cloud sandbox IPC channel contracts look correct; ensure handlers stay in sync

The cloud-sandbox-create and cloud-sandbox-delete channel typings align with the renderer usage (name/projectId/taskDescription) and the CloudSandbox shape. This follows the shared IPC typing pattern well; just make sure the main-process handlers in cloud-ipcs.ts and any tRPC wrappers use exactly these shapes so window.ipcRenderer.invoke/tRPC calls remain type-safe end to end.

Also applies to: 184-204

apps/desktop/src/renderer/screens/main/components/WorkspaceView/ContentView/TabsContent/WebView/WebView.tsx (1)

7-29: WebView lifecycle wiring and cleanup look correct

The ref handling and event listener setup/teardown are solid and should avoid leaks or stale handlers when the URL changes or the component unmounts.

… access

adds githubToken field to sandbox creation request so the e2b sandbox can clone private repositories using the user's github credentials
@caffeinum caffeinum changed the title feat(desktop): add cloud workspace with yolocode e2b integration feat(desktop): add cloud workspaces using yolocode.ai integration Nov 30, 2025
@github-actions
Copy link

github-actions bot commented Dec 7, 2025

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Database (Neon) View Branch

Preview updates automatically with new commits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants