Understanding the Core Config Directory Structure in the Continue IDE

The core/config directory serves as the central nervous system of the Continue IDE, transforming static user-authored YAML and Markdown files into strongly-typed runtime configuration objects that power the entire application architecture.

The continuedev/continue repository organizes its configuration logic within the core/config package, establishing a clear separation between user-facing configuration files and the internal runtime state. This architectural decision enables multiple IDE extensions—VS Code, JetBrains, and others—to consume a unified configuration API while maintaining consistent behavior across platforms.

The Architectural Role of core/config

The configuration layer acts as a single source of truth that bridges the gap between user-editable files and the live application state. When a user modifies .continue/config.yaml or creates a new profile in .continue/profiles/, the core/config package handles validation, parsing, and distribution of those changes to the LLM orchestration layer, context providers, and web-based UI components.

At the top of this hierarchy sits ConfigHandler.ts, which exposes an async API that the rest of the repository depends on. The handler coordinates multiple specialized loaders to build a complete ContinueConfig object defined in core/types.ts.

Directory Layout and Key Responsibilities

The core/config package is organized into functional subdirectories, each handling a specific aspect of configuration management:

YAML Parsing and Validation

The yaml/ subdirectory contains the low-level parsing logic. The file loadYaml.ts reads raw YAML content, validates it against the expected schema, and returns a ConfigResult<ContinueConfig> type. This is the entry point for converting static text into typed objects.

Profile Management

The profile/ directory handles profiles—discrete sets of configuration that users can swap at runtime. Key implementations include:

  • LocalProfileLoader.ts – Reads a single profile from a file or folder and constructs a valid ContinueConfig instance
  • ProfileLifecycleManager.ts – Manages creation, selection, and cleanup of profiles (located at the top level of core/config/)

Workspace-Scoped Configuration

The workspace/ subdirectory contains workspaceBlocks.ts, which loads configuration specific to individual workspace directories. This includes rule-dot-files that live alongside project code, allowing teams to commit shared configuration into version control.

Markdown-Based Rules

The markdown/ directory enables declarative configuration through Markdown files. loadMarkdownRules.ts parses these files to extract skills and rules that surface as quick commands in the UI, bridging documentation and executable configuration.

Shared and Utility Components

  • sharedConfig.ts – Stores global values like allowAnonymousTelemetry that persist across all profiles
  • util/validation.ts – Contains validation helpers used throughout the loading pipeline
  • loadLocalAssistants.ts – Discovers .continue/agents, .continue/assistants, and .continue/configs files across the workspace

The Configuration Loading Pipeline

The relationship between core/config and the overall architecture follows a clear data flow:


+-------------------+          +-------------------+
|   IDE (VS Code,   |  <--->   |   ConfigHandler   |
|   JetBrains, ...) |          |   (core/config)   |
+-------------------+          +-------------------+
         ^                               ^
         |                               |
   UI actions                 loadYaml    loadLocalAssistants
   (refresh, change profile)      |             |
                                  v             v
                         +-----------------------------+
                         |   ContinueConfig (type)     |
                         |   (core/types.ts)           |
                         +-----------------------------+

IDE Integration – IDE implementations in extensions/vscode and extensions/intellij instantiate ConfigHandler, passing a concrete IDE interface implementation. The handler uses this interface to discover workspace directories via ide.getWorkspaceDirs() and to read file contents.

Profile Discovery – On startup, ConfigHandler calls loadProfiles(), which invokes loadLocalAssistants.ts to scan for configuration files. Each discovered file receives its own LocalProfileLoader instance.

Serialization for UI – The web UI consumes configuration through ConfigHandler.getSerializedConfig(), which returns a BrowserSerializedContinueConfig object safe for transmission over the webview bridge.

Key Implementation Files

File Role
core/config/ConfigHandler.ts Central orchestrator that loads profiles, merges configs, and exposes the async API
core/config/loadLocalAssistants.ts Discovers agent and assistant definitions across the workspace
core/config/profile/LocalProfileLoader.ts Reads individual profile files and builds typed configuration objects
core/config/yaml/loadYaml.ts Transforms YAML strings into typed ContinueConfig instances
core/config/workspace/workspaceBlocks.ts Handles per-workspace rule files
core/config/markdown/loadMarkdownRules.ts Loads Markdown-based skill definitions
core/config/ProfileLifecycleManager.ts Manages profile state transitions
core/config/sharedConfig.ts Houses cross-profile global settings

Practical Code Examples

Instantiating the ConfigHandler

IDE extensions initialize the configuration layer by creating a ConfigHandler instance with the appropriate dependencies:

import { ConfigHandler } from "core/config/ConfigHandler.js";
import { MyIDE } from "./my-ide.js";
import { MyLogger } from "./my-logger.js";

const ide = new MyIDE();               // implements the IDE interface
const llmLogger = new MyLogger();      // implements ILLMLogger

// Construction triggers initial loading
const cfgHandler = new ConfigHandler(ide, llmLogger);

// Wait for initialization before accessing config
await cfgHandler.isInitialized;

// Retrieve the fully-resolved configuration
const configResult = await cfgHandler.loadConfig();
console.log("Loaded models:", configResult.config?.models.map(m => m.model));

Reacting to Configuration Changes

When users edit configuration files, the IDE extension triggers a refresh:

// File-watcher handler within the IDE extension
ide.onFileChange(async (filepath) => {
  if (filepath.endsWith("config.yaml")) {
    // Force cascade reload of all profiles
    await cfgHandler.refreshAll("User edited config.yaml");
  }
});

Registering Custom Context Providers at Runtime

Extensions can inject custom functionality by registering context providers directly with the handler:

import type { IContextProvider } from "core/index.js";

class PrivateKnowledgeProvider implements IContextProvider {
  get description() {
    return {
      title: "private-knowledge",
      displayTitle: "Private Knowledge Base",
      description: "Queries internal documentation",
      type: "normal",
    };
  }

  async getContextItems(query, extras) {
    // Implementation details...
    return [{ content: "Result", name: "doc", description: "Internal doc" }];
  }

  async loadSubmenuItems() { return []; }
}

// Register after ConfigHandler initialization
cfgHandler.registerCustomContextProvider(new PrivateKnowledgeProvider());

Summary

  • The core/config package translates static YAML and Markdown files into the live ContinueConfig objects that drive the application
  • ConfigHandler.ts serves as the central coordinator, managing profile loading, shared configuration, and UI serialization
  • The directory is organized by function: yaml/ for parsing, profile/ for runtime profiles, workspace/ for project-specific rules, and markdown/ for skill definitions
  • All IDE extensions depend on this layer, consuming configuration through the async API exposed by ConfigHandler
  • The architecture supports hot-reloading through refreshAll() and runtime extensibility via registerCustomContextProvider()

Frequently Asked Questions

What is the difference between profiles and workspace configuration in Continue?

Profiles are complete configuration sets managed by LocalProfileLoader.ts and ProfileLifecycleManager.ts that define models, context providers, and commands. Workspace configuration refers to rule files specific to a project directory, loaded by workspaceBlocks.ts, which augment the active profile with project-specific constraints without replacing it.

How does Continue handle configuration changes while the IDE is running?

The ConfigHandler exposes a refreshAll() method that re-parses all configuration files and rebuilds the internal state. IDE extensions trigger this method through file watchers when they detect changes to .continue/config.yaml or related files, ensuring the runtime state stays synchronized with disk contents.

Where are the TypeScript interfaces for Continue's configuration defined?

The primary type definitions reside in core/types.ts, which declares the ContinueConfig interface and all related types. The yaml/loadYaml.ts module validates raw configuration against these types, returning a ConfigResult<ContinueConfig> that guarantees type safety throughout the application.

How does the ConfigHandler communicate configuration to the web-based UI?

The handler provides getSerializedConfig(), which returns a BrowserSerializedContinueConfig object. This stripped-down, serializable representation crosses the webview bridge to the React-based UI, allowing the settings panel and chat interface to reflect the current configuration without exposing internal implementation details.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →