Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions .changeset/jetbrains-restart-loading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@kilocode/kilo-jetbrains": patch
---

Recover the JetBrains backend when startup or restart loading is interrupted by stale connection failures.
8 changes: 8 additions & 0 deletions packages/kilo-jetbrains/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,14 @@ For blocking I/O in coroutines, move the dispatcher switch inside the callee usi
- For state-driven updates, assert that the component state matches after flushing coroutines and draining the EDT.
- For retained Swing components, assert that expand/collapse, update, and no-op paths work correctly without rebuilding the component tree.

### Integration Test Timeouts

- Prefer deterministic synchronization over timeouts: wait for explicit state transitions, event emissions, fake server hooks, latches, or coroutine completions that prove the system reached the expected condition.
- Use timeouts only when an integration test cannot otherwise protect the suite from a stuck process, external boundary, or coroutine. Treat them as watchdogs, not as the mechanism that makes the test pass.
- When a timeout is necessary, define one named timeout or wait helper near the top of the test file and reuse it. Do not scatter literal timeout values through individual assertions.
- Timeout failures should include the last observed state and useful logs or errors so CI explains what blocked progress.
- Do not use `delay`, sleeps, or repeated polling to guess when asynchronous work is done unless the behavior under test is timing-specific.

## Dependencies

- **Always bundle third-party libraries with the plugin.** Do not rely on libraries bundled with the IntelliJ platform (e.g. OkHttp, Gson, Guava, kotlinx-serialization-json). The IDE's bundled versions change across releases without notice and can cause version collisions, classloader conflicts, or silent API breakage. Declare all third-party dependencies as `implementation` in the relevant `build.gradle.kts` so they ship inside the plugin JAR and load from the plugin's own classloader.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ class KiloBackendAppService private constructor(
private suspend fun reconnect() {
mutex.withLock {
val current = _appState.value
if (current is KiloAppState.Ready || current is KiloAppState.Connecting || current is KiloAppState.Loading || current is KiloAppState.MigrationRequired) {
if (current is KiloAppState.Ready || current is KiloAppState.Loading || current is KiloAppState.MigrationRequired) {
log.info("reconnect: already ${current::class.simpleName} — skipping")
return
}
Expand Down Expand Up @@ -442,6 +442,7 @@ class KiloBackendAppService private constructor(
} catch (e: CancellationException) {
throw e
} catch (e: Exception) {
ensureActive()
log.warn("Application start failed: ${e.message}")
captureLoad("Backend Load Failed", start, mapOf(
"errorCount" to errors.size.toString(),
Expand Down
Loading
Loading