Kilo Code is an open source AI coding agent for VS Code that generates code from natural language, automates tasks, and supports 500+ AI models.
This is a pnpm monorepo using Turbo for task orchestration:
src/- VSCode extension (core logic, API providers, tools)webview-ui/- React frontend (chat UI, settings)packages/- Shared packages (types,ipc,telemetry,cloud)jetbrains/- JetBrains plugin (Kotlin + Node.js host)apps/- E2E tests, Storybook, docs
Key source directories:
src/api/providers/- AI provider implementations (50+ providers)src/core/tools/- Tool implementations (ReadFile, ApplyDiff, ExecuteCommand, etc.)src/services/- Services (MCP, browser, checkpoints, code-index)packages/agent-runtime/- Standalone agent runtime (runs extension without VS Code)
The @kilocode/agent-runtime package enables running Kilo Code agents as isolated Node.js processes without VS Code.
┌─────────────────────┐ fork() ┌─────────────────────┐
│ Agent Manager │ ───────────────▶│ Agent Process │
│ │◀───── IPC ─────▶│ (extension host) │
└─────────────────────┘ └─────────────────────┘
- ExtensionHost: Hosts the Kilo Code extension with a complete VS Code API mock
- MessageBridge: Bidirectional IPC communication (request/response with timeout)
- ExtensionService: Orchestrates host and bridge lifecycle
Agents are forked processes configured via the AGENT_CONFIG environment variable:
import { fork } from "child_process"
const agent = fork(require.resolve("@kilocode/agent-runtime/process"), [], {
env: {
AGENT_CONFIG: JSON.stringify({
workspace: "/path/to/project",
providerSettings: { apiProvider: "anthropic", apiKey: "..." },
mode: "code",
autoApprove: false,
}),
},
stdio: ["pipe", "pipe", "pipe", "ipc"],
})
agent.on("message", (msg) => {
if (msg.type === "ready") {
agent.send({ type: "sendMessage", payload: { type: "newTask", text: "Fix the bug" } })
}
})| Direction | Type | Description |
|---|---|---|
| Parent → Agent | sendMessage |
Send user message to extension |
| Parent → Agent | injectConfig |
Update extension configuration |
| Parent → Agent | shutdown |
Gracefully terminate agent |
| Agent → Parent | ready |
Agent initialized |
| Agent → Parent | message |
Extension message |
| Agent → Parent | stateChange |
State updated |
Code running in agent processes can check for the AGENT_CONFIG environment variable. This is set by the agent manager when spawning processes:
if (process.env.AGENT_CONFIG) {
// Running as spawned agent - disable worker pools, etc.
}The Agent Manager follows a read-shared, write-isolated pattern:
- Read: Get config (models, API settings) from extension via
provider.getState() - Write: Inject state via
AGENT_CONFIGenv var when spawning - each agent gets isolated config
fork(agentRuntimePath, [], {
env: { AGENT_CONFIG: JSON.stringify({ workspace, providerSettings, mode, sessionId }) },
})This ensures parallel agents have independent state with no race conditions or file I/O conflicts.
pnpm install # Install all dependencies
pnpm build # Build extension (.vsix)
pnpm lint # Run ESLint
pnpm check-types # TypeScript type checking- Translation:
.kilocode/skills/translation/SKILL.md- Translation and localization guidelines
- Add Missing Translations:
.kilocode/workflows/add-missing-translations.md- Run/add-missing-translationsto find and fix missing translations
Each PR requires a changeset unless it's documentation-only or internal tooling. Create one with:
pnpm changesetFormat (in .changeset/<random-name>.md):
---
"kilo-code": patch
---
Brief description of the change- Use
patchfor fixes,minorfor features,majorfor breaking changes
Keep changesets concise and feature-oriented as they appear directly in release notes.
- Only for actual changes: Documentation-only or internal tooling changes do not need a changeset.
- User-focused: Avoid technical descriptions, code references, or PR numbers. Readers may not know the codebase.
- Concise: Use a one-liner for small fixes. For larger features, a few words or a short sentence is sufficient.
Kilo Code is a fork of Roo Code. We periodically merge upstream changes using scripts in scripts/kilocode/.
To minimize merge conflicts when syncing with upstream, mark Kilo Code-specific changes in shared code with kilocode_change comments.
Single line:
const value = 42 // kilocode_changeMulti-line:
// kilocode_change start
const foo = 1
const bar = 2
// kilocode_change endNew files:
// kilocode_change - new fileCode in these directories is Kilo Code-specific and doesn't need markers:
jetbrains/- JetBrains pluginagent-manager/directories- Any path containing
kilocodein filename or directory name - `src/services/autocomplete/ - Autocomplete service
All modifications to core extension code (files that exist in upstream Roo Code) require markers:
src/(except Kilo-specific subdirectories listed above)webview-ui/packages/(shared packages)
Keep changes to core extension code minimal to reduce merge conflicts during upstream syncs.
-
Test Coverage:
- Before attempting completion, always make sure that any code changes have test coverage
- Ensure all tests pass before submitting changes
- The vitest framework is used for testing; the
vi,describe,test,it, etc functions are defined by default intsconfig.jsonand therefore don't need to be imported fromvitest - Tests must be run from the same directory as the
package.jsonfile that specifiesvitestindevDependencies - Run tests with:
pnpm test <relative-path-from-workspace-root> - Do NOT run tests from project root - this causes "vitest: command not found" error
- Tests must be run from inside the correct workspace:
- Backend tests:
cd src && pnpm test path/to/test-file(don't includesrc/in path) - UI tests:
cd webview-ui && pnpm test src/path/to/test-file
- Backend tests:
- Example: For
src/tests/user.spec.ts, runcd src && pnpm test tests/user.spec.tsNOTpnpm test src/tests/user.spec.ts - Test File Naming Convention:
- Monorepo default:
.spec.ts/.spec.tsx
- Monorepo default:
-
Lint Rules:
- Never disable any lint rules without explicit user approval
-
Error Handling:
- Never use empty catch blocks - always log or handle the error
- Handle expected errors explicitly, or omit try-catch if the error should propagate
- Consider user impact when deciding whether to throw or log errors
-
Styling Guidelines:
- Use Tailwind CSS classes instead of inline style objects for new markup
- VSCode CSS variables must be added to webview-ui/src/index.css before using them in Tailwind classes
- Example:
<div className="text-md text-vscode-descriptionForeground mb-2" />instead of style objects