mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
Add deep analysis of decoupling Roo Code from VS Code
Comprehensive architectural analysis covering: - VS Code API dependency map (177/383 files, categorized by API surface) - Identification of the "Big Three" coupled files (Task.ts, ClineProvider.ts, webviewMessageHandler.ts) - Assessment of existing decoupling infrastructure (vscode-shim, packages/core, CLI app) - Proposed platform interface definitions (Storage, Terminal, Workspace, Editor, UI) - Phased migration plan from shim-based to interface-based architecture - Risk assessment and key metrics for tracking progress https://claude.ai/code/session_01813hRqbRLCrSitMdQQVr2c
This commit is contained in:
parent
5773af8ddd
commit
6384ba3532
1 changed files with 525 additions and 0 deletions
525
DECOUPLING_ANALYSIS.md
Normal file
525
DECOUPLING_ANALYSIS.md
Normal file
|
|
@ -0,0 +1,525 @@
|
|||
# Decoupling Roo Code from VS Code: Deep Analysis
|
||||
|
||||
## Executive Summary
|
||||
|
||||
Roo Code is a sophisticated AI coding assistant currently packaged as a VS Code extension with **~383 TypeScript source files** in `src/`, of which **~177 files (46%)** import from the `vscode` module. The codebase has already made significant progress toward decoupling through a monorepo architecture with shared packages, a `vscode-shim` package, and a working CLI application. However, the core orchestration layer (`Task.ts`, `ClineProvider.ts`, `webviewMessageHandler.ts`) remains deeply coupled to VS Code APIs.
|
||||
|
||||
This analysis maps the full dependency surface, identifies decoupling boundaries, and proposes a phased architecture for making Roo Code truly platform-agnostic.
|
||||
|
||||
---
|
||||
|
||||
## 1. Current Architecture Overview
|
||||
|
||||
### Monorepo Structure
|
||||
|
||||
```
|
||||
Roo-Code/
|
||||
├── src/ # VS Code extension (main codebase, 383 files)
|
||||
├── webview-ui/ # React frontend (Vite + Tailwind)
|
||||
├── apps/
|
||||
│ ├── cli/ # CLI app (Ink/React TUI)
|
||||
│ ├── web-roo-code/ # Next.js marketing + cloud dashboard
|
||||
│ ├── web-evals/ # Evaluation suite
|
||||
│ └── vscode-e2e/ # E2E tests
|
||||
├── packages/
|
||||
│ ├── types/ # Shared TypeScript types (ZERO vscode deps)
|
||||
│ ├── core/ # Platform-agnostic logic (ZERO vscode deps)
|
||||
│ ├── vscode-shim/ # VS Code API mock (ZERO external deps)
|
||||
│ ├── cloud/ # Cloud services
|
||||
│ ├── telemetry/ # Analytics
|
||||
│ └── ipc/ # Inter-process communication
|
||||
```
|
||||
|
||||
### How the CLI Already Works
|
||||
|
||||
The CLI (`apps/cli/`) demonstrates the current decoupling strategy:
|
||||
|
||||
1. **Module hijacking**: Intercepts `require("vscode")` calls via `Module._resolveFilename`
|
||||
2. **vscode-shim injection**: Returns `createVSCodeAPI()` mock when extension code requests the `vscode` module
|
||||
3. **Same bundle**: Loads the same compiled `extension.js` bundle that VS Code uses
|
||||
4. **Message-based communication**: Extension and CLI communicate through a `postMessage` protocol
|
||||
|
||||
This approach works but is fundamentally a **shim strategy** rather than a **clean architecture strategy**. The extension code still thinks it's running in VS Code.
|
||||
|
||||
---
|
||||
|
||||
## 2. VS Code API Dependency Map
|
||||
|
||||
### By API Category (across 177 files)
|
||||
|
||||
| Category | Occurrences | Files | Severity |
|
||||
|----------|------------|-------|----------|
|
||||
| `vscode.workspace` (config, folders, documents, diagnostics) | ~236 | 64 | **Critical** |
|
||||
| `vscode.window` (editors, dialogs, notifications, terminals) | ~336 | 48 | **Critical** |
|
||||
| `vscode.ExtensionContext` / lifecycle | ~92 | 45 | **High** |
|
||||
| `vscode.Uri` / path handling | ~75 | 29 | **Medium** |
|
||||
| `vscode.Diagnostic` / language features | ~77 | 6 | **Medium** |
|
||||
| `vscode.Range`, `Position`, `TextDocument` | ~71 | 10 | **Medium** |
|
||||
| `vscode.OutputChannel` / logging | ~46 | 20 | **Low** |
|
||||
| `vscode.WebviewPanel` / webview rendering | ~35 | 10 | **Low** (UI-specific) |
|
||||
| `vscode.Terminal` | ~7 | 3 | **Medium** |
|
||||
| `vscode.LanguageModelChat` (Copilot LM API) | ~12 | 2 | **Low** (optional) |
|
||||
| `vscode.CodeAction` | ~13 | 1 | **Low** (UI-specific) |
|
||||
|
||||
### Most-Coupled Files (the "Big Three")
|
||||
|
||||
| File | Lines | vscode refs | Role |
|
||||
|------|-------|-------------|------|
|
||||
| `src/core/webview/webviewMessageHandler.ts` | 3,611 | 109 | Routes all webview messages |
|
||||
| `src/core/webview/ClineProvider.ts` | 3,612 | 41 | Manages task lifecycle + webview |
|
||||
| `src/core/task/Task.ts` | 4,873 | 2 | Core task orchestration |
|
||||
|
||||
Notably, `Task.ts` has only **2 direct vscode references** (both `vscode.workspace.getConfiguration` calls), making it nearly decoupled already. The remaining coupling is indirect through imported modules.
|
||||
|
||||
### Already Decoupled (~206 files, 54%)
|
||||
|
||||
These modules have **zero** `vscode` imports:
|
||||
|
||||
- **API providers** (30+ files): `src/api/providers/` - All except `vscode-lm.ts`
|
||||
- **API transforms** (8 files): Stream processing, format conversion
|
||||
- **Shared utilities** (24 files): Types, modes, tools, cost calculation
|
||||
- **Pure utilities** (16 files): Token counting, config, errors, JSON schema
|
||||
- **`packages/types`**: All domain type definitions
|
||||
- **`packages/core`**: Custom tools, message utils, debug logging, worktree service
|
||||
|
||||
---
|
||||
|
||||
## 3. Coupling Analysis by Domain
|
||||
|
||||
### 3.1 Storage & Configuration (HIGH coupling)
|
||||
|
||||
**Current state**: All persistent state flows through `vscode.ExtensionContext`:
|
||||
- `context.globalState` - Key-value store for settings, task history, UI state
|
||||
- `context.secrets` - API keys and tokens
|
||||
- `context.globalStorageUri` - File-based storage path
|
||||
|
||||
**Key files**:
|
||||
- `src/core/config/ContextProxy.ts` - Wraps ExtensionContext with typed accessors
|
||||
- `src/core/config/ProviderSettingsManager.ts` - Multi-profile API config storage
|
||||
- `src/utils/storage.ts` - Storage path resolution
|
||||
|
||||
**Decoupling approach**: Extract a `StorageService` interface:
|
||||
```typescript
|
||||
interface StorageService {
|
||||
get<T>(key: string): T | undefined
|
||||
set<T>(key: string, value: T): Promise<void>
|
||||
getSecret(key: string): Promise<string | undefined>
|
||||
setSecret(key: string, value: string): Promise<void>
|
||||
getStoragePath(): string
|
||||
}
|
||||
```
|
||||
|
||||
**Existing precedent**: `vscode-shim` already implements `Memento` and `SecretStorage` backed by JSON files.
|
||||
|
||||
### 3.2 File System Operations (MEDIUM coupling)
|
||||
|
||||
**Current state**: Hybrid approach mixing Node.js `fs` and `vscode.workspace.fs`:
|
||||
- File read/write in tools: Mostly Node.js `fs/promises` (already portable)
|
||||
- Workspace-aware operations: `vscode.workspace.fs.stat()`, `.readFile()`, `.writeFile()`
|
||||
- Path resolution: `vscode.workspace.workspaceFolders`, `vscode.Uri.file()`
|
||||
|
||||
**Key files**:
|
||||
- `src/core/tools/ReadFileTool.ts`, `WriteToFileTool.ts`, `EditFileTool.ts` - Use Node.js `fs`
|
||||
- `src/integrations/workspace/WorkspaceTracker.ts` - Uses `vscode.workspace.fs`
|
||||
- `src/utils/path.ts` - `getWorkspacePath()` depends on `vscode.workspace.workspaceFolders`
|
||||
|
||||
**Decoupling approach**: The tool implementations are mostly portable. The key abstraction needed is workspace path resolution:
|
||||
```typescript
|
||||
interface WorkspaceService {
|
||||
getWorkspacePath(): string
|
||||
getWorkspaceFolders(): string[]
|
||||
resolveRelativePath(relativePath: string): string
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 Terminal / Command Execution (MEDIUM coupling)
|
||||
|
||||
**Current state**: Uses VS Code's integrated terminal API:
|
||||
- `vscode.window.createTerminal()` - Terminal creation
|
||||
- Shell integration APIs - Command tracking, exit codes
|
||||
- `vscode.env.clipboard` - Terminal output capture (clipboard workaround)
|
||||
|
||||
**Key files**:
|
||||
- `src/integrations/terminal/Terminal.ts` - VS Code terminal wrapper
|
||||
- `src/integrations/terminal/TerminalRegistry.ts` - Terminal lifecycle management
|
||||
|
||||
**Decoupling approach**: Extract a `TerminalService` interface:
|
||||
```typescript
|
||||
interface TerminalService {
|
||||
executeCommand(command: string, cwd: string): Promise<TerminalResult>
|
||||
getActiveTerminals(): TerminalInfo[]
|
||||
createTerminal(options: TerminalOptions): Terminal
|
||||
}
|
||||
```
|
||||
|
||||
**Note**: The CLI would use Node.js `child_process`, while VS Code would use its terminal API. The vscode-shim already stubs this but doesn't execute processes.
|
||||
|
||||
### 3.4 Editor Integration (LOW priority for decoupling)
|
||||
|
||||
**Current state**: Deep integration with VS Code editor features:
|
||||
- `DiffViewProvider` - Custom diff view with streaming decorations
|
||||
- `EditorUtils` - Tab management, document access, selections
|
||||
- `CodeActionProvider` - Quick fix actions
|
||||
- Diagnostics integration - Error/warning tracking
|
||||
|
||||
**Key files**:
|
||||
- `src/integrations/editor/DiffViewProvider.ts` - 49 vscode references
|
||||
- `src/integrations/editor/EditorUtils.ts` - Tab and document management
|
||||
- `src/integrations/diagnostics/index.ts` - Language diagnostics
|
||||
|
||||
**Decoupling approach**: These are inherently editor-specific features. Rather than abstracting them, they should remain in the VS Code adapter layer. Non-VS Code targets would provide alternative implementations (e.g., CLI shows diffs in terminal, web shows diffs in Monaco).
|
||||
|
||||
### 3.5 Webview Communication (HIGH coupling, but well-structured)
|
||||
|
||||
**Current state**: Type-safe message protocol between extension and webview:
|
||||
- `ExtensionMessage` (50+ types) - Extension to webview
|
||||
- `WebviewMessage` (70+ types) - Webview to extension
|
||||
- `ExtensionState` (100+ fields) - Full state sync
|
||||
|
||||
**Key files**:
|
||||
- `src/core/webview/ClineProvider.ts` - Webview provider (3,612 lines)
|
||||
- `src/core/webview/webviewMessageHandler.ts` - Message router (3,611 lines)
|
||||
- `packages/types/src/vscode-extension-host.ts` - Protocol types
|
||||
|
||||
**Decoupling insight**: The message protocol is **already transport-agnostic**. The types in `packages/types` define the contract. Only the transport layer (VS Code's `postMessage`) is platform-specific. This could easily use WebSocket, IPC, or HTTP instead.
|
||||
|
||||
### 3.6 Notifications & User Interaction (LOW-MEDIUM coupling)
|
||||
|
||||
**Current state**: Uses VS Code's notification system:
|
||||
- `vscode.window.showErrorMessage()` / `showInformationMessage()` / `showWarningMessage()`
|
||||
- `vscode.window.showInputBox()` - User prompts
|
||||
- `vscode.window.showOpenDialog()` - File picker
|
||||
- `vscode.window.showQuickPick()` - Selection UI
|
||||
|
||||
**Decoupling approach**: Abstract behind a `UserInteractionService`:
|
||||
```typescript
|
||||
interface UserInteractionService {
|
||||
showNotification(level: 'info' | 'warn' | 'error', message: string): void
|
||||
promptInput(options: InputOptions): Promise<string | undefined>
|
||||
selectFile(options: FilePickerOptions): Promise<string | undefined>
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. What's Already Working Well
|
||||
|
||||
### 4.1 The `packages/` Layer (Fully Decoupled)
|
||||
|
||||
| Package | VS Code deps | Status |
|
||||
|---------|-------------|--------|
|
||||
| `@roo-code/types` | None | Production-ready, shared everywhere |
|
||||
| `@roo-code/core` | None | Custom tools, message utils, worktree service |
|
||||
| `@roo-code/vscode-shim` | None | Complete VS Code API mock (~8,000 lines) |
|
||||
| `@roo-code/cloud` | None | Cloud service integration |
|
||||
| `@roo-code/telemetry` | None | PostHog analytics |
|
||||
| `@roo-code/ipc` | None | Inter-process communication |
|
||||
|
||||
### 4.2 API Provider Layer (Fully Decoupled)
|
||||
|
||||
All 30+ AI provider implementations in `src/api/providers/` work without VS Code, with the sole exception of `vscode-lm.ts` (GitHub Copilot integration, inherently VS Code-specific).
|
||||
|
||||
### 4.3 The CLI App (Working Non-VS Code Target)
|
||||
|
||||
`apps/cli/` proves the architecture can work outside VS Code via the shim approach. It successfully:
|
||||
- Loads and activates the extension
|
||||
- Runs tasks with the full tool set
|
||||
- Provides a React-based terminal UI
|
||||
- Manages state without VS Code storage
|
||||
|
||||
---
|
||||
|
||||
## 5. The Core Problem: The "Big Three" Files
|
||||
|
||||
The three largest and most coupled files contain the majority of the business logic that would need to be extracted:
|
||||
|
||||
### 5.1 `Task.ts` (4,873 lines) - Nearly Decoupled
|
||||
|
||||
Despite its size, `Task.ts` has remarkably low direct VS Code coupling:
|
||||
- **Only 2 `vscode.` references**: Both are `vscode.workspace.getConfiguration()` calls
|
||||
- **Indirect coupling**: Through imported modules (`Terminal`, `WorkspaceTracker`, etc.)
|
||||
- **Core loop is pure**: The `attemptApiRequest()` generator and tool execution flow are framework-agnostic
|
||||
|
||||
**What it manages**:
|
||||
- API conversation history
|
||||
- Tool execution orchestration
|
||||
- Message streaming and parsing
|
||||
- Context window management
|
||||
- Checkpoint management
|
||||
- Auto-approval logic
|
||||
|
||||
**To fully decouple**: Replace the 2 `getConfiguration()` calls with injected config, and ensure all imported services use interfaces.
|
||||
|
||||
### 5.2 `ClineProvider.ts` (3,612 lines) - The VS Code Bridge
|
||||
|
||||
This is the **central adapter** between VS Code and the core logic. It:
|
||||
- Implements `vscode.WebviewViewProvider`
|
||||
- Manages the task stack (`clineStack: Task[]`)
|
||||
- Initializes all services (MCP, Code Index, Browser, Skills)
|
||||
- Handles state serialization for the webview
|
||||
- Coordinates between multiple subsystems
|
||||
|
||||
**41 `vscode.` references** covering:
|
||||
- Webview creation and HTML content
|
||||
- Extension context access
|
||||
- Workspace folder resolution
|
||||
- Theme detection
|
||||
- Output channel logging
|
||||
|
||||
**This file should remain VS Code-specific** but be refactored into a thin adapter that delegates to a platform-agnostic `TaskManager` service.
|
||||
|
||||
### 5.3 `webviewMessageHandler.ts` (3,611 lines) - Message Router
|
||||
|
||||
The highest coupling (109 `vscode.` references) because it handles every message from the UI:
|
||||
- Opens files in editor (`vscode.window.showTextDocument`)
|
||||
- Manages VS Code configuration (`vscode.workspace.getConfiguration`)
|
||||
- Shows dialogs and notifications
|
||||
- Accesses workspace state
|
||||
- Manages terminal operations
|
||||
|
||||
**Most of the logic here is business logic wrapped in VS Code API calls**. It should be split into:
|
||||
1. A platform-agnostic message handler (business logic)
|
||||
2. A VS Code adapter (UI operations)
|
||||
|
||||
---
|
||||
|
||||
## 6. Proposed Decoupling Architecture
|
||||
|
||||
### Target Architecture
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Platform Adapters │
|
||||
├──────────────┬────────────────┬──────────────────────────────┤
|
||||
│ VS Code │ CLI │ Web / Other │
|
||||
│ Adapter │ Adapter │ Adapter │
|
||||
│ (src/) │ (apps/cli/) │ (future) │
|
||||
│ │ │ │
|
||||
│ Implements: │ Implements: │ Implements: │
|
||||
│ - Webview │ - Ink TUI │ - WebSocket server │
|
||||
│ - Terminal │ - child_proc │ - HTTP API │
|
||||
│ - Editor │ - File-based │ - Browser-based │
|
||||
│ - Storage │ storage │ storage │
|
||||
└──────┬───────┴───────┬────────┴──────────────┬───────────────┘
|
||||
│ │ │
|
||||
▼ ▼ ▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Platform Interfaces │
|
||||
│ (packages/platform or packages/interfaces) │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ StorageService │ FileSystemService │
|
||||
│ TerminalService │ WorkspaceService │
|
||||
│ EditorService │ UserInteractionService │
|
||||
│ NotificationService │ DiagnosticsService │
|
||||
│ OutputService │ ThemeService │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Core Engine │
|
||||
│ (packages/engine or refactored src/core) │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ TaskManager │ MessageRouter │
|
||||
│ ToolExecutor │ PromptBuilder │
|
||||
│ ConversationManager │ ContextManager │
|
||||
│ CheckpointManager │ AutoApprovalEngine │
|
||||
│ │ │
|
||||
│ Dependencies: @roo-code/types, @roo-code/core │
|
||||
│ VS Code deps: NONE │
|
||||
└──────────────────────┬───────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────────────────────────────────────────────┐
|
||||
│ Shared Packages (existing) │
|
||||
├──────────────────────────────────────────────────────────────┤
|
||||
│ @roo-code/types │ @roo-code/core │
|
||||
│ @roo-code/cloud │ @roo-code/telemetry │
|
||||
│ @roo-code/ipc │ @roo-code/vscode-shim (for legacy) │
|
||||
└──────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Interface Definitions
|
||||
|
||||
The key interfaces that need to be defined:
|
||||
|
||||
```typescript
|
||||
// packages/platform/src/storage.ts
|
||||
interface StorageService {
|
||||
get<T>(key: string): T | undefined
|
||||
set<T>(key: string, value: T): Promise<void>
|
||||
getSecret(key: string): Promise<string | undefined>
|
||||
setSecret(key: string, value: string): Promise<void>
|
||||
deleteSecret(key: string): Promise<void>
|
||||
getStoragePath(): string
|
||||
}
|
||||
|
||||
// packages/platform/src/terminal.ts
|
||||
interface TerminalService {
|
||||
createTerminal(options: TerminalOptions): TerminalHandle
|
||||
executeCommand(command: string, cwd: string): Promise<CommandResult>
|
||||
getTerminals(): TerminalHandle[]
|
||||
disposeTerminal(id: string): void
|
||||
}
|
||||
|
||||
interface CommandResult {
|
||||
exitCode: number
|
||||
stdout: string
|
||||
stderr: string
|
||||
}
|
||||
|
||||
// packages/platform/src/workspace.ts
|
||||
interface WorkspaceService {
|
||||
getWorkspacePath(): string
|
||||
getWorkspaceFolders(): WorkspaceFolder[]
|
||||
getConfiguration<T>(section: string, key: string): T | undefined
|
||||
onConfigurationChange(callback: (e: ConfigChangeEvent) => void): Disposable
|
||||
getDiagnostics(uri?: string): Diagnostic[]
|
||||
}
|
||||
|
||||
// packages/platform/src/editor.ts
|
||||
interface EditorService {
|
||||
openFile(path: string, options?: OpenFileOptions): Promise<void>
|
||||
showDiff(original: string, modified: string, title: string): Promise<void>
|
||||
getActiveFilePath(): string | undefined
|
||||
getOpenFiles(): string[]
|
||||
}
|
||||
|
||||
// packages/platform/src/ui.ts
|
||||
interface UserInteractionService {
|
||||
showNotification(level: 'info' | 'warn' | 'error', msg: string): void
|
||||
promptInput(options: InputOptions): Promise<string | undefined>
|
||||
selectFromList<T>(items: T[], options: ListOptions): Promise<T | undefined>
|
||||
showProgress<T>(title: string, task: (report: ProgressReporter) => Promise<T>): Promise<T>
|
||||
}
|
||||
|
||||
// packages/platform/src/output.ts
|
||||
interface OutputService {
|
||||
createChannel(name: string): OutputChannel
|
||||
log(channel: string, message: string): void
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Phased Migration Plan
|
||||
|
||||
### Phase 1: Define Platform Interfaces (Low risk)
|
||||
|
||||
**Goal**: Create `packages/platform` with interface definitions.
|
||||
|
||||
1. Define all platform service interfaces (storage, terminal, workspace, editor, UI, output)
|
||||
2. Define a `PlatformContext` container that holds all services
|
||||
3. Create VS Code implementations of each interface wrapping current code
|
||||
4. No behavior change - just formalize existing contracts
|
||||
|
||||
**Estimated scope**: ~15-20 new files, 0 behavioral changes
|
||||
|
||||
### Phase 2: Extract Core Engine (Medium risk)
|
||||
|
||||
**Goal**: Move business logic from `src/core/` to `packages/engine`.
|
||||
|
||||
1. **Extract `TaskManager`** from `ClineProvider.ts`:
|
||||
- Task creation, lifecycle management, stack operations
|
||||
- Remove VS Code webview code
|
||||
- Accept `PlatformContext` via constructor injection
|
||||
|
||||
2. **Migrate `Task.ts`** (minimal changes needed):
|
||||
- Replace 2 `vscode.workspace.getConfiguration()` calls with injected config
|
||||
- Ensure all service dependencies come through `PlatformContext`
|
||||
|
||||
3. **Split `webviewMessageHandler.ts`**:
|
||||
- Business logic handlers → `packages/engine/MessageRouter`
|
||||
- VS Code UI operations → `src/adapters/VSCodeUIAdapter`
|
||||
|
||||
4. **Move tool implementations** to engine:
|
||||
- Tools already use callback interfaces
|
||||
- Replace direct `vscode.workspace.fs` calls with `FileSystemService`
|
||||
- Replace `vscode.window.showInputBox` calls with `UserInteractionService`
|
||||
|
||||
**Estimated scope**: Refactor ~20-30 files, create ~10-15 new files
|
||||
|
||||
### Phase 3: Create Platform Adapters (Low risk)
|
||||
|
||||
**Goal**: Implement platform-specific adapters.
|
||||
|
||||
1. **VS Code Adapter** (`src/` or `packages/vscode-adapter`):
|
||||
- Thin wrapper delegating to engine via `PlatformContext`
|
||||
- Webview provider remains VS Code-specific
|
||||
- Terminal, editor, storage implementations
|
||||
|
||||
2. **CLI Adapter** (refactor `apps/cli/`):
|
||||
- Replace vscode-shim approach with direct platform interface implementations
|
||||
- Node.js `child_process` for `TerminalService`
|
||||
- File-based `StorageService`
|
||||
- No-op or simple `EditorService`
|
||||
|
||||
3. **Web Adapter** (future):
|
||||
- WebSocket-based `TerminalService`
|
||||
- HTTP API-based `StorageService`
|
||||
- Monaco-based `EditorService`
|
||||
|
||||
### Phase 4: Retire vscode-shim for Core Usage (Low risk)
|
||||
|
||||
**Goal**: The shim becomes optional (only needed for legacy/third-party extensions).
|
||||
|
||||
1. CLI uses native platform interfaces instead of mocking VS Code
|
||||
2. Extension code no longer imports `vscode` in core engine
|
||||
3. vscode-shim remains available for edge cases
|
||||
|
||||
---
|
||||
|
||||
## 8. Risk Assessment
|
||||
|
||||
### Low Risk
|
||||
- **API provider layer**: Already decoupled, no changes needed
|
||||
- **Type definitions**: Already in shared package
|
||||
- **Prompt generation**: Nearly pure, minimal coupling
|
||||
- **Tool base class**: Already uses callback interfaces
|
||||
|
||||
### Medium Risk
|
||||
- **Task.ts refactoring**: Large file but low coupling. Risk is in regressions from refactoring a 4,873-line file
|
||||
- **Tool implementations**: Some use `vscode.Uri` and `vscode.workspace.fs` but alternatives are straightforward
|
||||
- **Configuration management**: Need to ensure all settings paths are covered
|
||||
|
||||
### High Risk
|
||||
- **webviewMessageHandler.ts split**: 3,611 lines with 109 vscode references. Every message type needs careful routing
|
||||
- **ClineProvider.ts refactoring**: Central coordinator with complex state management. Extracting TaskManager while preserving behavior is delicate
|
||||
- **Terminal integration**: VS Code's shell integration provides unique capabilities (command tracking, exit codes) that are hard to replicate
|
||||
|
||||
### Mitigations
|
||||
- Extensive test coverage before refactoring (current test infrastructure exists)
|
||||
- Feature flags to switch between old and new code paths
|
||||
- The CLI already validates that the shim approach works, proving the interfaces are sufficient
|
||||
- Incremental migration - extract one service at a time
|
||||
|
||||
---
|
||||
|
||||
## 9. Key Metrics
|
||||
|
||||
| Metric | Current | After Phase 2 | After Phase 4 |
|
||||
|--------|---------|---------------|---------------|
|
||||
| Files importing `vscode` | 177 (46%) | ~50 (13%) | ~30 (8%) |
|
||||
| Core engine vscode deps | ~20 files | 0 | 0 |
|
||||
| Platform interface coverage | 0% | ~80% | 100% |
|
||||
| Non-VS Code targets | 1 (CLI via shim) | 1 (CLI via interfaces) | 3+ |
|
||||
| vscode-shim required | Yes (CLI) | Optional | Optional |
|
||||
|
||||
---
|
||||
|
||||
## 10. Recommendations
|
||||
|
||||
### Immediate Actions (No Architectural Change)
|
||||
1. **Remove the 2 `vscode.workspace.getConfiguration` calls from `Task.ts`** - Pass config values through constructor or method parameters instead
|
||||
2. **Create `packages/platform`** with interface definitions only - No implementation changes
|
||||
3. **Audit `webviewMessageHandler.ts`** - Categorize each message handler as "business logic" vs "VS Code UI operation"
|
||||
|
||||
### Strategic Direction
|
||||
1. **Invest in the interface layer, not the shim** - The vscode-shim is clever but adds maintenance burden. Clean interfaces are better long-term.
|
||||
2. **Keep ClineProvider as a thin adapter** - Don't try to make the webview provider portable. Instead, extract the logic it delegates to.
|
||||
3. **Prioritize `Task.ts` extraction** - It's the highest-value, lowest-risk target since it already has minimal coupling.
|
||||
4. **Consider the webview-ui as already portable** - The React frontend communicates via messages and could work with any backend transport (WebSocket, HTTP, IPC).
|
||||
|
||||
### What NOT to Do
|
||||
1. **Don't abstract the editor features** (diff view, decorations, code actions) - These are inherently VS Code-specific and should stay in the adapter
|
||||
2. **Don't create a unified UI abstraction** - The CLI (Ink/React), webview (React), and potential web UI (React) should each have their own presentation layer
|
||||
3. **Don't force all VS Code code into a single adapter** - Some features (CodeActionProvider, status bar) are legitimately VS Code-only features
|
||||
Loading…
Add table
Reference in a new issue