Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
b2d303c
feat: basic autocomplete support
catrielmuller Dec 8, 2025
68b17f3
feat: add wrapper detection for jetbrains only
catrielmuller Dec 8, 2025
75c9dcf
refactor: improve language detection
catrielmuller Dec 8, 2025
1ad8e3a
feat: jetbrains autocomplete improvements
catrielmuller Dec 9, 2025
57dc5a9
refactor: disable autocomplete by default on Jetbrains IDEs
catrielmuller Dec 9, 2025
f85428b
refactor: revert FIM compat
catrielmuller Dec 9, 2025
ed086d9
refactor: minimal change on the vscode autocomplete implementation
catrielmuller Dec 9, 2025
548f8ee
feat: device auth workflow
catrielmuller Dec 3, 2025
414282a
refactor: add changeset
catrielmuller Dec 3, 2025
d261094
refactor: add translations for device auth
catrielmuller Dec 3, 2025
50a6647
Update webview-ui/src/App.tsx
catrielmuller Dec 3, 2025
314d490
refactor: isolate the deviceAuthHandler
catrielmuller Dec 3, 2025
80e04db
refactor: isolate the changes
catrielmuller Dec 3, 2025
830c8b7
refactor: add kilocode_change
catrielmuller Dec 3, 2025
0dbbbda
refactor: refactor Device Auth Card
catrielmuller Dec 3, 2025
b4dc917
refactor: improve qrcode generation
catrielmuller Dec 3, 2025
b7b0f67
refactor: improve changelog
catrielmuller Dec 9, 2025
9da4ece
refactor: rebase // fix conflicts
catrielmuller Dec 9, 2025
a37b44d
Merge pull request #4178 from Kilo-Org/catrielmuller/extension-device…
catrielmuller Dec 9, 2025
33c9eab
fix: jetbrains open external urls
catrielmuller Dec 4, 2025
37ed530
Add update section to CLI documentation
dosire Dec 9, 2025
b6f703f
Update src/services/ghost/classic-auto-complete/GhostInlineCompletion…
catrielmuller Dec 9, 2025
c3a9ece
Merge pull request #4182 from Kilo-Org/catrielmuller/jetbrains-open-e…
catrielmuller Dec 9, 2025
44e7ae6
docs: update cloud agent documentation (#4336)
pandemicsyn Dec 9, 2025
38730d7
Update apps/kilocode-docs/docs/cli.md
emilieschario Dec 9, 2025
e0b46c3
Apply suggestions from code review
emilieschario Dec 9, 2025
70c5bf2
Merge pull request #4335 from Kilo-Org/dosire-patch-1
emilieschario Dec 9, 2025
62005f5
refactor: fix test
catrielmuller Dec 9, 2025
5b3bbe9
refactor: simplify the document mock
catrielmuller Dec 9, 2025
89b73cd
refactor: disable manual triggering options on jb
catrielmuller Dec 9, 2025
8a3a65f
refactor: update GhostServiceSettings tests
catrielmuller Dec 9, 2025
2da7051
Merge pull request #4330 from Kilo-Org/catrielmuller/jetbrains-ghost-…
catrielmuller Dec 9, 2025
7f349d0
Add Autocomplete to chat text box and track visible code (#3999)
hassoncs Dec 9, 2025
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/curly-jokes-cut.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": minor
---

JetBrains IDEs: Autocomplete is now available and can be enabled in Settings > Autocomplete.
11 changes: 11 additions & 0 deletions .changeset/gentle-plants-smile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"kilo-code": minor
---

Added a new device authorization flow for Kilo Gateway that makes it easier to connect your editor to your Kilo account. Instead of manually copying API tokens, you can now:

- Scan a QR code with your phone or click to open the authorization page in your browser
- Approve the connection from your browser
- Automatically get authenticated without copying any tokens

This streamlined workflow provides a more secure and user-friendly way to authenticate, similar to how you connect devices to services like Netflix or YouTube.
5 changes: 5 additions & 0 deletions .changeset/thin-dots-smoke.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": patch
---

Jetbrains - Fix open external urls
5 changes: 5 additions & 0 deletions .changeset/tidy-donuts-judge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"kilo-code": minor
---

Add Autocomplete support to the chat text box. It can be enabled/disabled using a new toggle in the autocomplete settings menu
15 changes: 8 additions & 7 deletions apps/kilocode-docs/docs/advanced-usage/cloud-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ Your work is always pushed to GitHub, ensuring nothing is lost.

## How Cloud Agents Work

- Each user receives an **isolated Linux container** with common dev tools preinstalled (Python, Node.js, git, etc.).
- Each user receives an **isolated Linux container** with common dev tools preinstalled (Node.js, git, gh CLI, etc.).
- All Cloud Agent chats share a **single container instance**, while each session gets its own workspace directory.
- When a session begins:

Expand All @@ -67,7 +67,7 @@ Your work is always pushed to GitHub, ensuring nothing is lost.
- Containers are **ephemeral**:
- Spindown occurs after inactivity
- Expect slightly longer setup after idle periods
- Inactive sessions are deleted after **7 days** during the beta
- Inactive cloud agent sessions are deleted after **7 days** during the beta, expired sessions are still accessible via the CLI

---

Expand Down Expand Up @@ -105,11 +105,12 @@ Cloud Agents are great for:

## Limitations and Guidance

- Each message can run for **up to 10 minutes**.
- Each message can run for **up to 15 minutes**.
Break large tasks into smaller steps; use a `plan.md` or `todo.md` file to keep scope clear.
- **Context is not persistent across messages yet.**
Kilo Code does not remember previous turns; persistent in-repo notes help keep it aligned.
- **Auto/YOLO mode is always on.**
- **Context is persistent across messages.**
Kilo Code remembers previous turns within the same session.
- **Auto/YOLO mode is always on.**
The agent will modify code without prompting for confirmation.
- **Saved sessions** in the sidebar are not yet shared between logins or restorable locally.
- **Sessions are restorable locally** and local sessions can be resumed in Cloud Agent.
- **Sessions prior to December 9th 2025** may not be accessible in the web UI.
- **MCP support is coming**, but **Docker-based MCP servers will _not_ be supported**.
6 changes: 6 additions & 0 deletions apps/kilocode-docs/docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ kilocode --continue

to start the CLI and begin a new task with your preferred model and relevant mode.

## Update

Upgrade the Kilo CLI package:

`npm update -g @kilocode/cli`

## What you can do with Kilo Code CLI

- **Plan and execute code changes without leaving your terminal.** Use your command line to make edits to your project without opening your IDE.
Expand Down
57 changes: 55 additions & 2 deletions jetbrains/host/src/rpcManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { IRemoteConsoleLog } from "../deps/vscode/vs/base/common/console.js"
import { FileType, FilePermission, FileSystemProviderErrorCode } from "../deps/vscode/vs/platform/files/common/files.js"
import * as fs from "fs"
import { promisify } from "util"
import { exec } from "child_process"
import { ConfigurationModel } from "../deps/vscode/vs/platform/configuration/common/configurationModels.js"
import { NullLogService } from "../deps/vscode/vs/platform/log/common/log.js"
import { ExtensionIdentifier } from "../deps/vscode/vs/platform/extensions/common/extensions.js"
Expand Down Expand Up @@ -307,9 +308,61 @@ export class RPCManager {
console.log("Get initial state")
return Promise.resolve({ isFocused: false, isActive: false })
},
$openUri(uri: UriComponents, uriString: string | undefined, options: any): Promise<boolean> {
async $openUri(uri: UriComponents, uriString: string | undefined, options: any): Promise<boolean> {
console.log("Open URI:", { uri, uriString, options })
return Promise.resolve(true)

try {
// Use the uriString if provided, otherwise construct from uri components
const urlToOpen = uriString || this.constructUriString(uri)

if (!urlToOpen) {
console.error("No valid URL to open")
return false
}

console.log("Opening URL in browser:", urlToOpen)

// Open URL in default browser based on platform
const execAsync = promisify(exec)
let command: string

switch (process.platform) {
case "darwin": // macOS
command = `open "${urlToOpen}"`
break
case "win32": // Windows
command = `start "" "${urlToOpen}"`
break
default: // Linux and others
command = `xdg-open "${urlToOpen}"`
break
}

await execAsync(command)
console.log("Successfully opened URL in browser")
return true
} catch (error) {
console.error("Failed to open URI:", error)
return false
}
},
constructUriString(uri: UriComponents): string | null {
if (!uri) return null

const scheme = uri.scheme || "https"
const authority = uri.authority || ""
const path = uri.path || ""
const query = uri.query ? `?${uri.query}` : ""
const fragment = uri.fragment ? `#${uri.fragment}` : ""

// Construct the full URI
if (authority) {
return `${scheme}://${authority}${path}${query}${fragment}`
} else if (path) {
return `${scheme}:${path}${query}${fragment}`
}

return null
},
$asExternalUri(uri: UriComponents, options: any): Promise<UriComponents> {
console.log("As external URI:", { uri, options })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package ai.kilocode.jetbrains.actors

import ai.kilocode.jetbrains.commands.CommandRegistry
import ai.kilocode.jetbrains.commands.ICommand
import ai.kilocode.jetbrains.commands.registerSetContextCommands
import ai.kilocode.jetbrains.editor.registerOpenEditorAPICommands
import ai.kilocode.jetbrains.terminal.registerTerminalAPICommands
import ai.kilocode.jetbrains.util.doInvokeMethod
Expand Down Expand Up @@ -68,6 +69,7 @@ class MainThreadCommands(val project: Project) : MainThreadCommandsShape {
init {
registerOpenEditorAPICommands(project, registry)
registerTerminalAPICommands(project, registry)
registerSetContextCommands(project, registry)
// TODO other commands
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
// SPDX-FileCopyrightText: 2025 Weibo, Inc.
//
// SPDX-License-Identifier: Apache-2.0

package ai.kilocode.jetbrains.actors

import ai.kilocode.jetbrains.core.ExtensionIdentifier
import ai.kilocode.jetbrains.inline.InlineCompletionManager
import com.intellij.openapi.Disposable
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project

/**
* Language features related interface.
Expand Down Expand Up @@ -448,11 +446,26 @@ interface MainThreadLanguageFeaturesShape : Disposable {
* concrete implementations for all language feature registration methods.
* It acts as a bridge between the extension host and the IDE's language services.
*/
class MainThreadLanguageFeatures : MainThreadLanguageFeaturesShape {
class MainThreadLanguageFeatures(private val project: Project) : MainThreadLanguageFeaturesShape {
private val logger = Logger.getInstance(MainThreadLanguageFeatures::class.java)

/**
* Manager for inline completion providers.
* Handles registration, unregistration, and lifecycle management.
*/
private val inlineCompletionManager: InlineCompletionManager by lazy {
InlineCompletionManager(project)
}

override fun unregister(handle: Int) {
logger.info("Unregistering service: handle=$handle")

// Try to unregister from inline completion manager
try {
inlineCompletionManager.unregisterProvider(handle)
} catch (e: Exception) {
logger.warn("Failed to unregister inline completion provider: handle=$handle", e)
}
}

override fun registerDocumentSymbolProvider(handle: Int, selector: List<Map<String, Any?>>, label: String) {
Expand Down Expand Up @@ -614,7 +627,22 @@ class MainThreadLanguageFeatures : MainThreadLanguageFeaturesShape {
displayName: String?,
debounceDelayMs: Int?,
) {
logger.info("Registering inline completions support: handle=$handle, selector=$selector, supportsHandleDidShowCompletionItem=$supportsHandleDidShowCompletionItem, extensionId=$extensionId, yieldsToExtensionIds=$yieldsToExtensionIds, displayName=$displayName, debounceDelayMs=$debounceDelayMs")
logger.info("Registering inline completions support: handle=$handle, extensionId=$extensionId, displayName=$displayName")

try {
inlineCompletionManager.registerProvider(
handle = handle,
selector = selector,
supportsHandleDidShowCompletionItem = supportsHandleDidShowCompletionItem,
extensionId = extensionId,
yieldsToExtensionIds = yieldsToExtensionIds,
displayName = displayName,
debounceDelayMs = debounceDelayMs
)
logger.info("Successfully registered inline completion provider: handle=$handle")
} catch (e: Exception) {
logger.error("Failed to register inline completion provider: handle=$handle", e)
}
}

override fun registerInlineEditProvider(
Expand Down Expand Up @@ -709,5 +737,12 @@ class MainThreadLanguageFeatures : MainThreadLanguageFeaturesShape {

override fun dispose() {
logger.info("Disposing MainThreadLanguageFeatures resources")

// Dispose inline completion manager
try {
inlineCompletionManager.dispose()
} catch (e: Exception) {
logger.error("Error disposing inline completion manager", e)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

package ai.kilocode.jetbrains.actors

import com.intellij.ide.BrowserUtil
import com.intellij.openapi.Disposable
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project
import com.intellij.openapi.wm.WindowManager
import java.awt.Desktop
import java.net.URI

/**
Expand Down Expand Up @@ -73,29 +73,22 @@ class MainThreadWindow(val project: Project) : MainThreadWindowShape {
try {
logger.info("Opening URI: $uriString")

// Try to get URI
val actualUri = if (uriString != null) {
try {
URI(uriString)
} catch (e: Exception) {
// If URI string is invalid, try to build from URI components
createUriFromComponents(uri)
}
// Try to get URI string
val urlToOpen = if (uriString != null) {
uriString
} else {
createUriFromComponents(uri)
// Build from URI components
val actualUri = createUriFromComponents(uri)
actualUri?.toString()
}

return if (actualUri != null) {
// Check if Desktop operation is supported
if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
Desktop.getDesktop().browse(actualUri)
true
} else {
logger.warn("System does not support opening URI")
false
}
return if (urlToOpen != null) {
// Use IntelliJ's BrowserUtil which works reliably in JetBrains IDEs
BrowserUtil.browse(urlToOpen)
logger.info("Successfully opened URI in browser: $urlToOpen")
true
} else {
logger.warn("Cannot create valid URI")
logger.warn("Cannot create valid URI from components: $uri")
false
}
} catch (e: Exception) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package ai.kilocode.jetbrains.commands

import ai.kilocode.jetbrains.core.ContextManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.project.Project

/**
* Registers the setContext command for managing VSCode-style context keys.
*
* The setContext command allows the extension to set context values that can be used
* to control UI state and feature availability. This is commonly used by features like
* the GhostProvider (autocomplete) to enable/disable keybindings dynamically.
*
* @param project The current IntelliJ project
* @param registry The command registry to register commands with
*/
fun registerSetContextCommands(project: Project, registry: CommandRegistry) {
// Register the primary command
registry.registerCommand(
object : ICommand {
override fun getId(): String {
return "setContext"
}

override fun getMethod(): String {
return "setContext"
}

override fun handler(): Any {
return SetContextCommands(project)
}

override fun returns(): String? {
return "void"
}
},
)

// Register alias with underscore prefix for compatibility with VSCode
registry.registerCommandAlias("setContext", "_setContext")
}

/**
* Handles setContext command operations for managing context keys.
*
* This class provides the implementation for the setContext command, which allows
* setting context key-value pairs that can be used throughout the plugin to control
* feature availability and UI state.
*
* Example context keys used by GhostProvider:
* - kilocode.ghost.enableQuickInlineTaskKeybinding
* - kilocode.ghost.enableSmartInlineTaskKeybinding
*/
class SetContextCommands(val project: Project) {
private val logger = Logger.getInstance(SetContextCommands::class.java)
private val contextManager = ContextManager.getInstance(project)

/**
* Sets a context value for the given key.
*
* This method is called when the setContext command is executed from the extension.
* It stores the key-value pair in the ContextManager for later retrieval.
*
* @param key The context key to set (e.g., "kilocode.ghost.enableQuickInlineTaskKeybinding")
* @param value The value to set (typically Boolean, but can be String, Number, etc.)
* @return null (void return type)
*/
suspend fun setContext(key: String, value: Any?): Any? {
try {
logger.info("Setting context: $key = $value")
contextManager.setContext(key, value)
logger.debug("Context successfully set: $key")
} catch (e: Exception) {
logger.error("Failed to set context: $key = $value", e)
throw e
}

return null
}
}
Loading