Architecture Overview
Dline currently ships as a single VS Code extension with an embedded React Webview. This page walks through the main modules layer by layer and points to their source, so you can find the real entry point before changing anything.
Repository layout
Section titled “Repository layout”| Directory | Contents |
|---|---|
src/ | The extension: entry point, core logic, host adapters, shared code, and tests |
webview-ui/ | A separate React + Vite Webview project |
proto/ | Protobuf contracts; see Protobuf and ProtoBus |
scripts/ | Code generation, packaging, test, and build helpers |
docs/ | This documentation site (a separate Astro Starlight project) and the English changelog |
standalone/, src/standalone/, src/hosts/external/ | Code kept for a future standalone executable; the current release ships only the VS Code extension |
testing-platform/, tests/ | Standalone integration-test clients and extra tests such as Storybook specs |
src/core is a source grouping, not a separately deployed product.
Activation flow
Section titled “Activation flow”The package.json entry point is dist/extension.js, built from activate() in src/extension.ts. Startup runs in this order:
setupHostProvider()registers the VS Code implementations of the Webview, diff, review, terminal, and host bridge throughHostProvider.initialize();- the sidebar Webview provider is created and registered right away; its Controller is created later;
- legacy VS Code storage is cleaned up; Dline does not import Cline data (see Migrating from Cline for the manual steps);
createStorageContext()resolves the storage roots, andexportVSCodeStorageToSharedFiles()exports legacyExtensionContextstate to file storage;initialize()(insrc/common.ts) initializesStateManagerandModelRegistry, creates the Controller, attaches it to the Webview provider, and registers it as the orchestrator’s main Controller;- the editor panel serializer, test mode, and hooks are registered, followed by the VS Code commands.
Host boundary
Section titled “Host boundary”HostProvider in src/hosts/host-provider.ts keeps task and service modules independent of the editor API. The VS Code implementation lives in src/hosts/vscode/:
- each host bridge service method is implemented under
src/hosts/vscode/hostbridge/<service>/, for examplewindow/showMessage.ts; - requests are dispatched by
src/hosts/vscode/hostbridge-grpc-handler.ts, which uses a generated service configuration; - the VS Code terminal, diff, and review implementations live in the same directory.
Keep VS Code API calls inside the host and integration boundary.
Webview and Controller
Section titled “Webview and Controller”| Component | Source | Responsibility |
|---|---|---|
VscodeWebviewProvider | src/hosts/vscode/VscodeWebviewProvider.ts | Binds the VS Code sidebar |
WebviewProvider | src/core/webview/WebviewProvider.ts | Lifecycle shared by the sidebar and editor panels |
WebviewProviderRegistry | src/core/webview/WebviewProviderRegistry.ts | Tracks the sidebar and additional panels |
Controller | src/core/controller/index.ts | Coordinates tasks, state projection, RPC handlers, and Webview updates |
OrchestratorController | src/core/orchestrator/OrchestratorController.ts | Manages the main Controller, panel Controllers, Profile broadcasts, and parent/child tasks |
Each Webview provider owns one Controller. The React side boots from webview-ui/src/main.tsx, which renders App.tsx; shared extension state is provided by webview-ui/src/context/ExtensionStateContext.tsx.
RPC between the extension and the Webview uses ProtoBus request/response envelopes carried over VS Code postMessage, not a network gRPC connection.
Task runtime
Section titled “Task runtime”A task runs on a journaled kernel. The Controller holds one session/ActiveTaskSession.ts per open task, and every lifecycle change flows through these components:
| Source | Responsibility |
|---|---|
shell/Task.ts, shell/TaskShell.ts | The task’s public surface: open, start, submit input, respond, cancel, and terminate |
kernel/transition.ts | The pure transition function that validates every event against the task state |
kernel/hydrate.ts, kernel/recovery.ts | Rebuild the state from state.json and the journal when a task reopens, and recover interrupted work |
runtime/TaskRuntime.ts | Serializes events, commits them through the commit pipeline, and dispatches commands from the durable outbox |
stores/ | The journal, payload, and state stores behind each commit |
composition/ | Assembles a session’s runtime, stores, and executors, including the upgrade import of an earlier version’s conversation |
session/ActiveTaskSession.ts | Owns one open task’s resources and whether this window may write it |
session/TaskInteractionOwner.ts | Owns user interactions such as approval, retry, resume, Q&A, plan, and completion |
MessageChannel.ts, message-state.ts | Deliver messages serially and project the chat rows |
activity/TaskActivityStore.ts | Owns the task activities shown in chat and the Activities view |
All paths are relative to src/core/task/. Express a new lifecycle transition as an event, validate it in the kernel transition, then project it to the UI; do not add a parallel boolean lifecycle next to TaskRuntime. Only the window holding the task lock may write a task: until TaskShell.open() grants write ownership, the runtime refuses every event with a read_only rejection, and the Controller shows the task read-only.
| Location | Contents |
|---|---|
src/shared/tools.ts | Built-in tool identities, enum DlineDefaultTool |
src/core/prompts/tools/tool-specs.ts | Canonical tool descriptors, STANDARD_TOOL_SPECS |
src/core/prompts/tools/tool-ids.ts | Ordered tool IDs registered for Standard and Lite |
src/core/prompts/tools/provider-projector.ts | Projection to provider-native tool schemas |
src/core/prompts/tools/xml-tool-projector.ts | Projection to XML tool documentation |
src/core/task/tools/handlers/ | Runtime handler for each tool |
src/core/task/ToolExecutor.ts, src/core/task/tools/ToolExecutorCoordinator.ts | Tool execution coordination |
Native tools and XML tools are two projections of the same canonical descriptors. See Prompt Architecture for how prompts and tools relate, and Tool Execution Domain for how tool blocks run.
Providers and models
Section titled “Providers and models”buildApiHandler()insrc/core/api/index.tstakes the current mode’s Profile and, throughbuildApiHandlerFromProfile(), callscreateHandlerForProvider(), which picks a handler fromsrc/core/api/providers/byprofile.provider. An unknown provider ID throws.src/core/model-registry/ModelRegistry.tsis the runtime model catalog.- The API format
ApiFormatis defined inproto/dline/models/metadata.proto. Provider metadata and API format decide native tool, hosted tool, image, reasoning, and transport capabilities.
Networking
Section titled “Networking”Extension-side code must reach the network through src/shared/net.ts, not global fetch or a default Axios instance:
| Export | Use |
|---|---|
fetch | Ordinary network requests |
providerFetch | Provider API requests, counted in provider request observation |
getAxiosSettings() | Shared transport settings for Axios requests |
createOpenAIClient() | OpenAI-compatible SDK client that uses providerFetch |
mockFetchForTesting() | Replaces the shared transport within a bounded scope in tests |
createOpenAIClientForProfile(), which builds an OpenAI client for a Profile, lives in src/core/api/providers/openai-client-factory.ts. The Webview runs in a browser environment and may use the browser’s own fetch.
src/services/mcp/McpHub.ts is a reference-counted instance shared by multiple Controllers. It supports the stdio, sse, and streamableHttp transports; OAuth applies only to the two remote transports. MCP configuration never grants task approval by itself.