Technical guide for the Deep Code VS Code extension as implemented in the current codebase.
- Overview
- Features
- Code Structure
- Entry Points
- Core Components
- Webview Communication Architecture
- Data Flow
- Configuration
- Dependencies
- UI Design
Deep Code is a VS Code sidebar extension that provides a persistent AI chat interface with tool execution, skill loading, and support for DeepSeek defaults as well as OpenAI-compatible APIs.
- Webview-based chat UI with HTML/CSS templates under
resources/ - Persistent sessions stored under
~/.deepcode/projects/<projectCode>/ - Tool execution pipeline for
bash,read,write,edit, andAskUserQuestion - Skill discovery from
~/.agents/skills/,./.agents/skills/, and legacy./.deepcode/skills/ - DeepSeek-first defaults with configurable OpenAI-compatible API settings
- Sessioned Chat - Multiple conversations with persisted history and status
- Skills - Discover, select, auto-match, and inject skill documents into a session
- Tool Calls - Supports shell, file operations, and structured user clarification
- Markdown Rendering - Assistant responses are rendered with
markdown-it - Interrupt - Stop an active session from the UI
- Persistent Storage - Session index and message history are stored on disk
deepcode/
├── src/
│ ├── extension.ts # VS Code activation + webview wiring
│ ├── session.ts # Session manager, storage, status, skills
│ ├── prompt.ts # System prompt and tool definitions
│ └── tools/
│ ├── executor.ts # Tool dispatch
│ ├── bash-handler.ts # Persistent shell execution
│ ├── read-handler.ts # File, image, notebook, and PDF reads
│ ├── write-handler.ts # Full-file writes
│ ├── edit-handler.ts # Scoped replacements
│ ├── ask-user-question-handler.ts
│ └── state.ts # Read/snippet tracking for tool safety
├── resources/
│ ├── webview.html # Webview markup and frontend logic
│ ├── webview.css # Webview styles
│ └── deepcoding_icon.png
├── docs/
│ └── guide.md
├── package.json
└── tsconfig.json
Location: src/extension.ts
- Registers
DeepcodingViewProviderfor the sidebar view - Registers the
deepcode.openViewcommand - View type:
"deepcode.chatView"
Location: src/extension.ts
- Currently a no-op
Location: src/extension.ts
Responsible for:
- Webview initialization and backend/frontend message handling
- Creating the OpenAI-compatible client from
~/.deepcode/settings.json - Rendering assistant Markdown to HTML before sending it to the UI
- Loading sessions, updating session status, and sending skill lists
Location: src/session.ts
Responsible for:
- Session creation, updates, persistence, and active-session tracking
- Building OpenAI chat payloads from session history
- Injecting the system prompt, optional
AGENTS.mdinstructions, and selected skills - Running the tool-call loop and appending assistant/tool/system messages
- Status tracking (
pending,processing,waiting_for_user,completed,failed,interrupted)
Instruction lookup order:
./.deepcode/AGENTS.md~/.deepcode/AGENTS.md
Storage layout:
~/.deepcode/projects/<projectCode>/sessions-index.json~/.deepcode/projects/<projectCode>/<sessionId>.jsonl
Location: src/tools/executor.ts
Responsible for:
- Parsing tool calls from model responses
- Executing tool handlers (
bash,read,write,edit,AskUserQuestion) - Formatting tool results into JSON strings for tool messages
Location: resources/webview.html
Responsible for:
- Rendering chat bubbles for user, assistant, system, and tool messages
- Managing session selection, prompt history, and loading state
- Rendering skill selection UI and AskUserQuestion forms
The extension uses VS Code's Webview API for bidirectional communication between the extension backend and the UI frontend.
| Type | Payload | Description |
|---|---|---|
ready |
{} |
Webview signals it is ready to receive initial state |
requestSkills |
{} |
Request the currently available skill list |
userPrompt |
{ prompt: string, skills?: SkillInfo[] } |
Submit a prompt with optional selected skills |
interrupt |
{} |
Interrupt the active session |
createNewSession |
{} |
Start a new session |
selectSession |
{ sessionId: string } |
Load a specific session |
backToList |
{} |
Return to the session list view |
| Type | Payload | Description |
|---|---|---|
initializeEmpty |
{ sessions, status } |
Show an empty composer state |
loadSession |
{ sessionId, summary, status, sessions, messages } |
Load a session and its visible messages |
showSessionsList |
{ sessions } |
Refresh the session dropdown data |
skillsList |
{ skills } |
Update the available skill list |
sessionStatus |
{ sessionId, status } |
Update the status of the current session |
userMessage |
{ content } |
Append the raw user text bubble |
assistant |
{ html } |
Append a direct assistant HTML message, typically for failures |
appendMessage |
{ message, shouldConnect } |
Append a structured session message generated during execution |
loading |
{ value: boolean } |
Toggle the loading indicator |
- Webview sends
ready - Backend replies with the latest session or an empty state
- Webview requests skills with
requestSkills - User submits a prompt through
userPrompt - Backend posts
userMessage, setsloading, and hands off toSessionManager SessionManagercalls the model, appends messages, executes tools, and updates status- Backend pushes incremental updates with
appendMessage,sessionStatus,showSessionsList, andskillsList
User Input
↓
Webview sends "userPrompt" with optional selected skills
↓
SessionManager creates or updates the session
↓
Inject system prompt, optional `AGENTS.md` instructions, and loaded skills
↓
Build chat.completions payload from session history
↓
Call chat.completions.create()
↓
Append assistant message
↓
If tool calls exist: execute tools, append tool messages, loop
↓
If AskUserQuestion is returned: set status to waiting_for_user
↓
Persist state and notify the webview
Location: ~/.deepcode/settings.json
{
"env": {
"API_KEY": "sk-...",
"BASE_URL": "https://api.deepseek.com",
"MODEL": "deepseek-v4-pro"
},
"headers": {
"User-Agent": "Mozilla/5.0 ..."
},
"thinkingEnabled": true,
"reasoningEffort": "max",
"notify": "~/.deepcode/notify.sh"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
env.API_KEY |
string | Yes | - | API key for the configured provider |
env.BASE_URL |
string | No | https://api.deepseek.com |
Base URL for a DeepSeek or other OpenAI-compatible endpoint |
env.MODEL |
string | No | deepseek-v4-pro |
Model identifier passed to chat.completions.create() |
headers |
object | No | {} |
Extra HTTP headers passed to the OpenAI-compatible SDK client, useful for providers that require custom headers such as User-Agent |
thinkingEnabled |
boolean | No | true for deepseek-v4-flash and deepseek-v4-pro; otherwise false |
Enables the optional thinking request field when set to true |
reasoningEffort |
"high" or "max" |
No | "max" |
Controls DeepSeek thinking strength via reasoning_effort when thinking mode is enabled |
notify |
string | No | - | Executable script path triggered when a task ends in completed or failed, with DURATION set to the elapsed seconds |
From package.json:
-
openai
- OpenAI SDK used for chat completion calls
- Works with DeepSeek defaults and other compatible base URLs
-
markdown-it
- Markdown parser and renderer
- Converts assistant responses into HTML for the webview
-
gray-matter
- Parses skill frontmatter from
SKILL.md - Used when discovering skill name and description metadata
- Parses skill frontmatter from
-
ignore
- Applies
.gitignore-style matching in the read tool - Helps avoid ambiguous or ignored file-path matches
- Applies
-
@types/vscode
- TypeScript definitions for the VS Code API
-
@types/markdown-it
- TypeScript definitions for
markdown-it
- TypeScript definitions for
-
@types/node
- Node.js type definitions
-
typescript
- TypeScript compiler
- Uses VS Code theme variables rather than a fixed custom theme
- Distinct bubble treatments for user, assistant, system, and tool messages
- Loading indicator for in-progress requests
- HTML template:
resources/webview.html - CSS styles:
resources/webview.css
- Auto-scrolls to the newest messages
Entersends the promptShift + Enterinserts a newlineArrowUpandArrowDownnavigate prompt history when the caret is at the boundary- Session list, session switching, and new-session creation
- Skill picker in the composer
role === "user": plain text user bubblerole === "assistant"andmeta.asThinking !== true: standard assistant bubble with rendered Markdown HTML. When this message is appended during active processing, the frontend marks the session as completed and hides the loading indicator.role === "assistant"andmeta.asThinking === true: collapsible intermediate bubble (used for thinking messages or status updates like context compaction). The loading indicator remains visible after appending this message.role === "system"withmeta.skill: collapsible skill bubble that shows the loaded skill name and descriptionrole === "tool": collapsible tool bubble with success or error state;AskUserQuestiontool output renders an interactive form when the session status iswaiting_for_user
Deep Code is a VS Code AI assistant extension with:
- Session-based persistence under
~/.deepcode - A webview chat UI driven by structured backend/frontend messages
- DeepSeek-oriented defaults with configurable OpenAI-compatible API access
- Skill discovery and loading for session-specific behavior
- A multi-step tool execution loop including structured user clarification