Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
52 commits
Select commit Hold shift + click to select a range
d6c38ea
feat(mcp): persist MCP enabled state to config file
mikij Feb 21, 2026
82a8290
fix(mcp): resolve config path consistently and handle persistence errors
mikij Feb 21, 2026
58407b0
refactor(config): improve config file resolution priority
mikij Feb 23, 2026
f061cb2
fix(config): preserve MCP connections on config reload
mikij Feb 23, 2026
db3cf55
fix(config): find correct config file for MCP toggle persistence
mikij Feb 23, 2026
0da79ae
fix(config): skip managed config paths when determining where to writ…
mikij Feb 23, 2026
ea8fd54
fix(config): handle MCP toggle in read-only managed config
mikij Feb 23, 2026
a7bcb7d
Merge branch 'main' into fix/#565-mcp-toggle
mikij Feb 23, 2026
4b8738f
fix(config): resolve config path order mismatch and add change event …
mikij Feb 23, 2026
83730ae
Merge branch 'main' into fix/#565-mcp-toggle
mikij Feb 23, 2026
838149e
fix(config): remive try/catch
mikij Feb 23, 2026
f8d2627
fix(config): config writes go to the same location hierarchy as confi…
mikij Feb 23, 2026
2d6cfc5
fix(config): eliminates wasteful operations when toggling an MCP serv…
mikij Feb 23, 2026
7d4e872
fix(config): PR comments
mikij Feb 23, 2026
85b5b3f
fix(config): Added GlobalBus.emit() to update() to notify UI/watchers…
mikij Feb 23, 2026
71c50d4
Merge branch 'main' into fix/#565-mcp-toggle
mikij Feb 26, 2026
2537889
fix(config): addressing comments after conflict resolution
mikij Feb 26, 2026
2d8b32a
Merge branch 'main' into fix/#565-mcp-toggle
mikij Feb 26, 2026
582bafe
fix(config): addressed new set of PR comments
mikij Feb 26, 2026
51d638f
Merge branch 'main' into fix/#565-mcp-toggle
mikij Feb 26, 2026
122fb73
fix(config): addressed new set of PR comments
mikij Feb 26, 2026
fbbff14
Merge branch 'main' into fix/#565-mcp-toggle
mikij Mar 4, 2026
0aff250
chore(sdk): removing generated changes from PR
mikij Mar 4, 2026
ea6c8b2
fix(mcp): improve toggle logic and config search
mikij Mar 4, 2026
e61db48
fix(config): add file locking and fix state disposal order
mikij Mar 4, 2026
5a83ec0
fix(config): improve config file loading order and MCP handling
mikij Mar 4, 2026
e4990d6
fix(config): use parseJsonc instead of JSON.parse for inline config
mikij Mar 4, 2026
d9cfca5
docs(config): reorganize config resolution order comments
mikij Mar 4, 2026
b5b5ec1
refactor(config): update mcp config search order precedence
mikij Mar 4, 2026
d2fd238
fix(config): reverse directory depth sort for config file resolution
mikij Mar 4, 2026
dcee5c1
Merge branch 'main' into fix/#565-mcp-toggle
mikij Mar 4, 2026
8834242
fix(config): simplify mcp config file existence check
mikij Mar 4, 2026
6386ba2
refactor(config): improve mcp toggle validation and config path resol…
mikij Mar 5, 2026
701f796
Merge branch 'main' into fix/#565-mcp-toggle
mikij Mar 5, 2026
12c1151
Merge remote-tracking branch 'origin/main' into fix/#565-mcp-toggle
mikij Mar 14, 2026
54aa765
fix(config): remove premature Instance.dispose() call
mikij Mar 14, 2026
584dae3
feat(config): enhance cache management and config file precedence
mikij Mar 14, 2026
8b03048
feat(config): add reactive configuration update handling
mikij Mar 14, 2026
6c8201a
refactor(sdk): reorganize event types and standardize json formatting
mikij Mar 14, 2026
913945c
fix(vscode): correct config change event directory comparison
mikij Mar 14, 2026
1355367
feat(config): add boolean return to persistMcpToggle for success indi…
mikij Mar 14, 2026
ead0d9f
fix(vscode): correct config change handler to use reloadAfterAuthChange
mikij Mar 14, 2026
f93fdbb
fix(vscode): fix MCP toggle config change handling for worktrees
mikij Mar 14, 2026
2e43b29
fix(config): refine shared config detection for accurate state disposal
mikij Mar 14, 2026
48592d8
fix(config): ensure all workspaces refresh after shared config change
mikij Mar 14, 2026
f7d52e3
Merge branch 'main' into fix/#565-mcp-toggle
mikij Mar 15, 2026
c257437
fix(config): ensure all state is disposed when shared config changes
mikij Mar 15, 2026
8124de8
fix(worktree): refine shared config detection and add directory param…
mikij Mar 15, 2026
2e1a399
feat: adjust config/state disposal and refresh behavior to preserve a…
mikij Mar 15, 2026
e74b27a
fix(config): ensure state disposal runs for current directory regardl…
mikij Mar 15, 2026
f6b0332
feat(config): add .kilocode directory support as legacy config fallback
mikij Mar 15, 2026
ddc4e9b
Merge branch 'main' into fix/#565-mcp-toggle
mikij Mar 18, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions packages/app/src/context/global-sync/event-reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ export function applyDirectoryEvent(input: {
input.push(input.directory)
return
}
case "config.changed": {
const props = event.properties as { directory: string }
if (props.directory === input.directory) {
input.push(input.directory)
}
return
}
case "session.created": {
const info = (event.properties as { info: Session }).info
const result = Binary.search(input.store.session, info.id, (s) => s.id)
Expand Down
80 changes: 47 additions & 33 deletions packages/kilo-vscode/src/KiloProvider.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,42 @@
import * as path from "path"
import * as vscode from "vscode"
import { z } from "zod"
import { buildPreviewPath, getPreviewCommand, getPreviewDir, parseImage, trimEntries } from "./image-preview"
import { isAbsolutePath } from "./path-utils"
import type {
Config,
Event,
FilePartInput,
KiloClient,
Session,
SessionStatus,
Event,
TextPartInput,
FilePartInput,
Config,
} from "@kilocode/sdk/v2/client"
import { type KiloConnectionService, type KilocodeNotification, ServerStartupError } from "./services/cli-backend"
import type { EditorContext, CloudSessionData } from "./services/cli-backend/types"
import { FileIgnoreController } from "./services/autocomplete/shims/FileIgnoreController"
import { handleChatCompletionRequest } from "./services/autocomplete/chat-autocomplete/handleChatCompletionRequest"
import * as path from "path"
import * as vscode from "vscode"
import { z } from "zod"
import { buildPreviewPath, getPreviewCommand, getPreviewDir, parseImage, trimEntries } from "./image-preview"
import { isAbsolutePath } from "./path-utils"
import { handleChatCompletionAccepted } from "./services/autocomplete/chat-autocomplete/handleChatCompletionAccepted"
import { buildWebviewHtml } from "./utils"
import { handleChatCompletionRequest } from "./services/autocomplete/chat-autocomplete/handleChatCompletionRequest"
import { FileIgnoreController } from "./services/autocomplete/shims/FileIgnoreController"
import { ServerStartupError, type KiloConnectionService } from "./services/cli-backend"
import type { CloudSessionData, EditorContext } from "./services/cli-backend/types"
import { TelemetryProxy, type TelemetryPropertiesProvider } from "./services/telemetry"
import { buildWebviewHtml } from "./utils"
// legacy-migration start
import * as MigrationService from "./legacy-migration/migration-service"
// legacy-migration end
import {
sessionToWebview,
indexProvidersById,
filterVisibleAgents,
buildSettingPath,
mapSSEEventToWebviewMessage,
filterVisibleAgents,
flushPendingSessionRefresh as flushPendingSessionRefreshUtil,
getErrorMessage,
indexProvidersById,
isEventFromForeignProject,
mapCloudSessionMessageToWebviewMessage,
loadSessions as loadSessionsUtil,
flushPendingSessionRefresh as flushPendingSessionRefreshUtil,
mapCloudSessionMessageToWebviewMessage,
mapSSEEventToWebviewMessage,
sessionToWebview,
type SessionRefreshContext,
} from "./kilo-provider-utils"
import { MarketplaceService } from "./services/marketplace"
import { resolveProjectDirectory } from "./project-directory"
import { MarketplaceService } from "./services/marketplace"

type KiloProviderOptions = {
projectDirectory?: string | null
Expand Down Expand Up @@ -1122,7 +1122,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
* keyed by their real `provider.id` (e.g. "anthropic", "openai"). We re-key
* the map here so the rest of the code can use provider.id everywhere.
*/
private async fetchAndSendProviders(): Promise<void> {
private async fetchAndSendProviders(directory?: string): Promise<void> {
if (!this.client) {
// client not ready — serve from cache if available
if (this.cachedProvidersMessage) {
Expand All @@ -1132,7 +1132,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
}

try {
const workspaceDir = this.getWorkspaceDirectory()
const workspaceDir = directory ?? this.getWorkspaceDirectory()
const { data: response } = await this.client.provider.list({ directory: workspaceDir }, { throwOnError: true })

const normalized = indexProvidersById(response.all)
Expand All @@ -1158,7 +1158,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
/**
* Fetch agents (modes) from the backend and send to webview.
*/
private async fetchAndSendAgents(): Promise<void> {
private async fetchAndSendAgents(directory?: string): Promise<void> {
if (!this.client) {
if (this.cachedAgentsMessage) {
this.postMessage(this.cachedAgentsMessage)
Expand All @@ -1167,7 +1167,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
}

try {
const workspaceDir = this.getWorkspaceDirectory()
const workspaceDir = directory ?? this.getWorkspaceDirectory()
const { data: agents } = await this.client.app.agents({ directory: workspaceDir }, { throwOnError: true })

const { visible, defaultAgent } = filterVisibleAgents(agents)
Expand All @@ -1190,7 +1190,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
}
}

private async fetchAndSendSkills(): Promise<void> {
private async fetchAndSendSkills(directory?: string): Promise<void> {
if (!this.client) {
if (this.cachedSkillsMessage) {
this.postMessage(this.cachedSkillsMessage)
Expand All @@ -1199,7 +1199,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
}

try {
const workspaceDir = this.getWorkspaceDirectory()
const workspaceDir = directory ?? this.getWorkspaceDirectory()
const { data: skills } = await this.client.app.skills({ directory: workspaceDir }, { throwOnError: true })

const message = {
Expand Down Expand Up @@ -1313,7 +1313,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
/**
* Fetch backend config and send to webview.
*/
private async fetchAndSendConfig(): Promise<void> {
private async fetchAndSendConfig(directory?: string): Promise<void> {
if (!this.client || this.connectionState !== "connected") {
if (this.cachedConfigMessage) {
this.postMessage(this.cachedConfigMessage)
Expand All @@ -1322,7 +1322,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
}

try {
const workspaceDir = this.getWorkspaceDirectory()
const workspaceDir = directory ?? this.getWorkspaceDirectory()
const { data: config } = await this.client.config.get({ directory: workspaceDir }, { throwOnError: true })

const message = {
Expand Down Expand Up @@ -2222,13 +2222,14 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
* After instance.dispose() clears the server cache, the next request to each
* endpoint will re-initialize with the current auth state.
* This mirrors the TUI's sync.bootstrap() pattern.
* @param directory - Optional directory to use instead of workspace root (for worktree-specific refreshes)
*/
private async reloadAfterAuthChange(): Promise<void> {
private async reloadAfterAuthChange(directory?: string): Promise<void> {
await Promise.all([
this.fetchAndSendProviders(),
this.fetchAndSendAgents(),
this.fetchAndSendSkills(),
this.fetchAndSendConfig(),
this.fetchAndSendProviders(directory),
this.fetchAndSendAgents(directory),
this.fetchAndSendSkills(directory),
this.fetchAndSendConfig(directory),
this.fetchAndSendNotifications(),
])
}
Expand Down Expand Up @@ -2262,6 +2263,19 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
return
}

// Refresh config and dependent data when the server signals a config change
// Only refresh if the change affects the current session's directory, not background worktrees
// This prevents a config change in one worktree from overwriting the active panel's state
if (event.type === "config.changed") {
const currentSessionDir = this.currentSession
? (this.sessionDirectories.get(this.currentSession.id) ?? this.getWorkspaceDirectory())
: this.getWorkspaceDirectory()
if (event.properties.directory === currentSessionDir) {
void this.reloadAfterAuthChange(event.properties.directory)
return
}
}

// Forward relevant events to webview
// Side effects that must happen before the webview message is sent
if (event.type === "session.created" && !this.currentSession) {
Expand Down
Loading