fix(jetbrains): scope config warnings to the workspace directory - #13886
Merged
Merged
Conversation
Config warnings were fetched with no directory from an app-scoped service, so the CLI resolved the omitted directory to process.cwd(). Since the plugin spawned the CLI without setting a working directory, that cwd was the IDE's own cwd (typically $HOME on macOS), so every session showed a stray 'Automatic indexing is disabled in home and filesystem root directories' banner attributed to $HOME instead of the real project, and genuine project-local .kilo/kilo.json warnings were never surfaced at all. - Set the kilo serve child process's working directory to a plugin-owned empty directory (KiloBackendCliManager.workDir()) so any endpoint that omits directory lands somewhere harmless instead of $HOME. - Move config warnings from KiloAppStateDto (app-scoped, one instance per IDE) to KiloWorkspaceStateDto (directory-scoped), fetching them per-workspace via api.configWarnings(directory = directory) and refreshing them in place on the global.config.updated SSE event. - Update SessionController to read workspace.warnings instead of app.warnings, and to reload the workspace instead of restarting the backend when warnings are present. Restarting never resolved a static warning, so 'Try again' just repeated it.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Files Reviewed (4 files)
Previous Review Summary (commit 102761b)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit 102761b)Status: 3 Issues Found | Recommendation: Address before merge Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (18 files)
Reviewed by grok-4.6 · Input: 85.1K · Output: 12K · Cached: 475.5K Review guidance: REVIEW.md from base branch |
Address review feedback: - Launch the global.config.updated refresh instead of awaiting it inside events.collect. connection.events is a shared MutableSharedFlow with SUSPEND overflow, so a slow fetch in the collector would stall chat and every other workspace. Matches KiloBackendAppService. - Fetch config warnings through a bounded client. The workspace api has callTimeout(0)/readTimeout(0), so a hung /config/warnings never threw and left the workspace on Connecting even though the required catalog had loaded. Restores the 'hung warnings do not prevent Ready' coverage that moved over from the app-level test. - Treat an existing cwd directory as success in workDir(). mkdirs() returns false when the directory already exists, so a concurrent spawn could make the CLI fall back to the inherited IDE cwd, reintroducing the $HOME resolution this helper prevents.
marius-kilocode
approved these changes
Sep 8, 2026
This was referenced Sep 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issue
Fixes #
Context
JetBrains sessions were showing a stray "Configuration warnings" banner reading
/Users/<you>: Automatic indexing is disabled in home and filesystem root directories..., attributed to$HOMEinstead of the real project. Clicking "Try again" restarted the whole CLI backend and re-showed the identical banner.Root cause:
KiloBackendAppService.fetchWarnings()called/config/warnings(a directory-scoped endpoint) from an app-scoped service (Service.Level.APP, one instance per IDE) with nodirectory. The CLI fell back toprocess.cwd(), andKiloBackendCliManagerspawnedkilo servewithout setting a working directory, so it inherited the IDE JVM's cwd —$HOMEon macOS. The CLI then built a real instance for$HOME, which trips the "no automatic indexing in home/root" safeguard and returns it as a config warning. Because warnings lived onKiloAppStateDto, that warning painted onto every session regardless of its actual directory, and genuine project-local.kilo/kilo.jsonwarnings were never fetched for the right directory in the first place.Implementation
Two independent fixes:
CLI working directory —
KiloBackendCliManagernow setsProcessBuilder.directory(...)to a plugin-owned empty directory (<IDE system path>/kilo/cwd, via the newworkDir()helper) before spawningkilo serve. Falls back to inheriting the IDE's cwd if that directory can't be created, so this can never break startup. This means any endpoint that omitsdirectoryin the future lands somewhere harmless instead of$HOME.Config warnings become workspace-scoped — moved
warningsoffKiloAppStateDtoand ontoKiloWorkspaceStateDto/KiloWorkspaceState.Ready, fetched per-directory viaapi.configWarnings(directory = directory)inKiloBackendWorkspace.load(), right after providers/agents/commands/skills finish loading. The fetch is sequential and outside the parallellaunchblock, and failures are swallowed (return empty list) so a slow or erroring warnings call can never fail the workspace load. Aglobal.config.updatedSSE handler refreshes just the warnings in place (viaReady.copy(warnings = ...)) without reloading the rest of the workspace data.SessionControllernow readsworkspace.warningsinstead ofapp.warningsfor the banner, telemetry, and retry decision. The retry-with-warnings path now callsworkspace.reload()instead ofapp.retryAsync()— restarting the backend never fixed a warning (it's derived from on-disk config, not connection state), so the old behavior just repeated the same banner after a full CLI restart.KiloBackendAppService.retry()no longer escalates torestartConnection("warnings remained after refresh")for aReadyapp state, since warnings are no longer part ofAppDataat all.Net effect: the false
$HOMEbanner disappears, and real project-local config warnings (e.g. malformed.kilo/kilo.json) will now actually surface, scoped to the right directory — which they never did before this change, since warnings were always fetched for whatever directorykilo servehappened to inherit.All changes are confined to
packages/kilo-jetbrains/; no CLI (packages/opencode/,packages/core/) or SDK changes.Screenshots / Video
N/A — no visual changes to the banner itself, only which directory's warnings it shows and whether "Try again" restarts the backend.
How to Test
Manual/local verification
./gradlew typecheck— passes (also runs automatically via the pre-push hook)../gradlew test— full suite passes. OneWorktreeSessionEditorManagerTestfailure appeared in one full run; confirmed pre-existing/flaky by re-running it in isolation (passed) and re-running the full suite (passed clean) — unrelated to any file touched in this change../gradlew :backend:test --tests "ai.kilocode.backend.cli.KiloBackendCliManagerEnvTest" --tests "ai.kilocode.backend.app.KiloBackendAppServiceTest" --tests "ai.kilocode.backend.workspace.KiloBackendWorkspaceTest" --tests "ai.kilocode.backend.rpc.KiloWorkspaceDtoMapperTest"— pass./gradlew :frontend:test --tests "ai.kilocode.client.session.controller.AppWatchingTest" --tests "ai.kilocode.client.session.controller.ConnectionDelayTest" --tests "ai.kilocode.client.session.ui.ConnectionPanelTest"— passReviewer test steps
./gradlew --no-configuration-cache runIdeSplitModefrompackages/kilo-jetbrains/, open a project that is not$HOME.kilo.logshows aCLI cwd: <IDE system path>/kilo/cwdline..kilo/kilo.jsonand save — confirm the banner now appears, scoped to that file's path.retry: restarted connectionline).global.config.updatedSSE path.Blocked checks and substitute verification
Ready, SSE refresh in place, failed/empty warnings not blockingReady, retry reloading the workspace instead of restarting the app) plus./gradlew typecheck/test.Checklist
@kilocode/kilo-jetbrainsis"private": trueand excluded from the changesets flow; no changeset needed.Get in Touch