diff --git a/.changeset/console-loading-logo.md b/.changeset/console-loading-logo.md new file mode 100644 index 00000000000..d39b44da157 --- /dev/null +++ b/.changeset/console-loading-logo.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Show the animated Kilo logo while the console and dashboard finish loading. diff --git a/.changeset/fair-gateway-statuses.md b/.changeset/fair-gateway-statuses.md new file mode 100644 index 00000000000..98724d132c8 --- /dev/null +++ b/.changeset/fair-gateway-statuses.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Preserve upstream error statuses for cloud session and KiloClaw gateway requests. diff --git a/.changeset/nullable-kilo-gateway-sdk.md b/.changeset/nullable-kilo-gateway-sdk.md new file mode 100644 index 00000000000..3b9c4b0b8c9 --- /dev/null +++ b/.changeset/nullable-kilo-gateway-sdk.md @@ -0,0 +1,5 @@ +--- +"@kilocode/sdk": patch +--- + +Preserve nullable Kilo gateway response fields in the generated TypeScript SDK. diff --git a/.changeset/restore-mercury-next-edit.md b/.changeset/restore-mercury-next-edit.md new file mode 100644 index 00000000000..1ed5c75bb5b --- /dev/null +++ b/.changeset/restore-mercury-next-edit.md @@ -0,0 +1,5 @@ +--- +"@kilocode/cli": patch +--- + +Restore Kilo Gateway-backed Mercury Next Edit completions. diff --git a/.changeset/stellar-forest-feedback.md b/.changeset/stellar-forest-feedback.md new file mode 100644 index 00000000000..98dd0d17c1d --- /dev/null +++ b/.changeset/stellar-forest-feedback.md @@ -0,0 +1,5 @@ +--- +"@kilocode/kilo-jetbrains": patch +--- + +Add Feedback & Support to the JetBrains empty session screen. diff --git a/.github/workflows/codeql-kotlin.yml b/.github/workflows/codeql-kotlin.yml new file mode 100644 index 00000000000..5f0cec56c87 --- /dev/null +++ b/.github/workflows/codeql-kotlin.yml @@ -0,0 +1,62 @@ +# kilocode_change - new file +name: "CodeQL Kotlin" + +on: + push: + branches: ["main"] + paths: + - "packages/kilo-jetbrains/**" + - ".github/workflows/codeql-kotlin.yml" + pull_request: + branches: ["main"] + paths: + - "packages/kilo-jetbrains/**" + - ".github/workflows/codeql-kotlin.yml" + schedule: + - cron: "29 10 * * 5" + workflow_dispatch: + +jobs: + analyze: + name: Analyze (java-kotlin) + runs-on: ubuntu-latest + permissions: + security-events: write + packages: read + actions: read + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v6 + + - name: Setup Bun + uses: ./.github/actions/setup-bun + + - name: Setup Java + uses: actions/setup-java@v4 + with: + distribution: temurin + java-version: "21" + + - name: Setup Gradle + uses: gradle/actions/setup-gradle@v4 + with: + cache-read-only: ${{ github.ref != 'refs/heads/main' }} + + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: java-kotlin + build-mode: manual + config-file: ./.github/codeql/codeql-config.yml + + - name: Build Java/Kotlin + shell: bash + run: ./gradlew typecheck --rerun-tasks --no-build-cache + working-directory: packages/kilo-jetbrains + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:java-kotlin" diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index b37055f328e..86b7a69a053 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -14,11 +14,11 @@ name: "CodeQL Advanced" on: push: - branches: [ "main" ] + branches: ["main"] pull_request: - branches: [ "main" ] + branches: ["main"] schedule: - - cron: '29 10 * * 5' + - cron: "29 10 * * 5" workflow_dispatch: jobs: @@ -45,12 +45,10 @@ jobs: fail-fast: false matrix: include: - - language: actions - build-mode: none - - language: java-kotlin - build-mode: manual - - language: javascript-typescript - build-mode: none + - language: actions + build-mode: none + - language: javascript-typescript + build-mode: none # CodeQL supports the following values keywords for 'language': 'actions', 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'rust', 'swift' # Use `c-cpp` to analyze code written in C, C++ or both # Use 'java-kotlin' to analyze code written in Java, Kotlin or both @@ -60,58 +58,24 @@ jobs: # If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how # your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages steps: - - name: Checkout repository - uses: actions/checkout@v6 + - name: Checkout repository + uses: actions/checkout@v6 - # Add any setup steps before running the `github/codeql-action/init` action. - # This includes steps like installing compilers or runtimes (`actions/setup-node` - # or others). This is typically only required for manual builds. - # - name: Setup runtime (example) - # uses: actions/setup-example@v1 - - name: Setup Bun - if: matrix.language == 'java-kotlin' - uses: ./.github/actions/setup-bun + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v4 + with: + languages: ${{ matrix.language }} + build-mode: ${{ matrix.build-mode }} + config-file: ./.github/codeql/codeql-config.yml + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. - - name: Setup Java - if: matrix.language == 'java-kotlin' - uses: actions/setup-java@v4 - with: - distribution: temurin - java-version: "21" + # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs + # queries: security-extended,security-and-quality - - name: Setup Gradle - if: matrix.language == 'java-kotlin' - uses: gradle/actions/setup-gradle@v4 - with: - cache-read-only: ${{ github.ref != 'refs/heads/main' }} - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v4 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - config-file: ./.github/codeql/codeql-config.yml - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - - # For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs - # queries: security-extended,security-and-quality - - # If the analyze step fails for one of the languages you are analyzing with - # "We were unable to automatically build your code", modify the matrix above - # to set the build mode to "manual" for that language. Then modify this step - # to build your code. - # ℹ️ Command-line programs to run using the OS shell. - # 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun - - name: Build Java/Kotlin - if: matrix.language == 'java-kotlin' - shell: bash - run: ./gradlew typecheck - working-directory: packages/kilo-jetbrains - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v4 - with: - category: "/language:${{matrix.language}}" + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v4 + with: + category: "/language:${{matrix.language}}" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a90022ec66e..c9301c042d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -32,6 +32,7 @@ jobs: - name: windows host: blacksmith-4vcpu-windows-2025 # kilocode_change runs-on: ${{ matrix.settings.host }} + timeout-minutes: 45 # kilocode_change defaults: run: shell: bash diff --git a/.kilo/plans/1780256109130-stellar-forest.md b/.kilo/plans/1780256109130-stellar-forest.md new file mode 100644 index 00000000000..3aafa6c0dd9 --- /dev/null +++ b/.kilo/plans/1780256109130-stellar-forest.md @@ -0,0 +1,109 @@ +# Plan: JetBrains Feedback & Support Button + +## Goal +Add the VS Code empty-state `Feedback & Support` affordance to the JetBrains plugin, including a non-modal popup with the same three destinations: + +- GitHub issues: `https://github.com/Kilo-Org/kilocode/issues/new/choose` +- Discord: `https://kilo.ai/discord` +- Customer support: `https://kilo.ai/support` + +The popup must hide when clicking outside or pressing Escape. + +## Findings + +- The JetBrains empty state is `packages/kilo-jetbrains/frontend/src/main/kotlin/ai/kilocode/client/session/ui/EmptySessionPanel.kt`. +- It already renders the logo, welcome copy, recents, and `Show History`; this is the right place to add the button. +- The VS Code implementation is: + - Button: `packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx` + - Popup content: `packages/kilo-vscode/webview-ui/src/components/chat/FeedbackDialog.tsx` + - Styling: `packages/kilo-vscode/webview-ui/src/styles/welcome.css` +- Local IntelliJ API source is available at `$INTELLIJ_REPO=/Users/kirillk/products/intellij-community`. +- IntelliJ popup API confirmed in local source: + - `JBPopupFactory.getInstance().createComponentPopupBuilder(content, focusComponent)` + - `setModalContext(false)` for non-modal context + - `setRequestFocus(false)` / `setFocusable(false)` if we want the popup not to steal focus + - `setCancelOnClickOutside(true)` for outside-click dismissal + - `setCancelKeyEnabled(true)` for Escape dismissal + - `setCancelOnWindowDeactivation(true)` and `setCancelOnOtherWindowOpen(true)` are available and appropriate for cleanup +- IntelliJ platform icons found in `AllIcons`: + - Feedback button: `AllIcons.Ide.Feedback` + - GitHub action: `AllIcons.Vcs.Vendors.Github` + - Support/help action: `AllIcons.Actions.Help` or `AllIcons.General.ContextHelp` + - Discord: no platform icon found. Add a Discord icon by borrowing the existing VS Code/kilo-ui Discord SVG artwork and adapting it into the JetBrains plugin resources with IntelliJ-compatible SVG colors and dark variant if needed. + +## Implementation Steps + +1. Add localized JetBrains bundle keys. + - Add base English strings to `frontend/src/main/resources/messages/KiloBundle.properties`: + - `feedback.button=Feedback & Support` + - `feedback.dialog.message=We'd love to hear your feedback or help with any issues you're experiencing.` + - `feedback.dialog.github=Report an issue on GitHub` + - `feedback.dialog.discord=Join our Discord community` + - `feedback.dialog.support=Customer Support` + - Reuse existing cancel text if present; otherwise add `common.cancel=Cancel` only if needed. + - Add matching keys to localized `KiloBundle_*.properties` files. If accurate translations are not already available from the VS Code i18n files, copy the VS Code translations for matching locales where practical and leave English fallback only if the JetBrains bundle mechanism supports it cleanly. + +2. Extend `EmptySessionPanel` UI. + - Add a new retained `FeedbackButton`, styled to match VS Code conceptually: + - feedback icon + `Feedback & Support` text + - dashed link-colored border + - transparent background + - hand cursor + - hover state fills with link color and flips foreground/background for contrast + - Use IntelliJ theme APIs instead of raw colors: + - link color: `JBUI.CurrentTheme.Link.Foreground.ENABLED` + - hover link color: `JBUI.CurrentTheme.Link.Foreground.HOVERED` if useful + - editor/panel background from existing session style or `UiStyle.Colors.editorBackground()` / component background + - spacing via `UiStyle.Gap` / `JBUI.Borders` + - rounded arc via `UiStyle.Arc.component()` or `JBUI.getInt("Button.arc", 6)` at paint time + - Add the feedback button below the existing `Show History` button in the empty-state south area, keeping the current centered layout. + - Keep Swing mutations on EDT and preserve retained-component behavior. + +3. Implement the feedback popup in frontend Swing code. + - Add a small popup builder method/class inside `EmptySessionPanel.kt` or a new nearby UI file if the file would become too large. + - Content should mirror VS Code: + - Kilo logo at top using existing `/icons/kilo-content.svg` + - message text + - three action buttons/rows for GitHub, Discord, and Customer Support + - every action should have an icon: `AllIcons.Vcs.Vendors.Github` for GitHub, the borrowed Discord SVG for Discord, and `AllIcons.Actions.Help` or `AllIcons.General.ContextHelp` for Customer Support + - optional Cancel button if it fits the JetBrains UX; Escape/outside click already dismisses + - Add the Discord icon asset under `frontend/src/main/resources/icons/` using the plugin's existing icon naming pattern, for example `discord.svg` and `discord_dark.svg` if the borrowed asset needs separate theme variants. + - Load the Discord icon with `IconLoader.getIcon("/icons/discord.svg", EmptySessionPanel::class.java)` or a small Kilo-owned icon object if multiple call sites need it. + - Use `BrowserUtil.browse(url)` to open links. + - Close the popup after opening a URL. + - Use `JBPopupFactory.createComponentPopupBuilder(content, null)` and configure: + - `.setModalContext(false)` + - `.setRequestFocus(false)` + - `.setFocusable(false)` unless keyboard tabbing inside popup is desired; if buttons need keyboard focus, use `.setFocusable(true)` with `.setRequestFocus(false)` + - `.setCancelOnClickOutside(true)` + - `.setCancelKeyEnabled(true)` + - `.setCancelOnWindowDeactivation(true)` + - `.setCancelOnOtherWindowOpen(true)` + - `.setResizable(false)` + - `.setMovable(false)` + - Show with `popup.showUnderneathOf(feedbackButton)`. + +4. Add test coverage in `EmptySessionPanelTest.kt`. + - Assert feedback button text uses `KiloBundle.message("feedback.button")`. + - Assert feedback button has hand cursor and visible border semantics. + - Add an injectable browse callback or popup action callback only if needed for testing without launching browsers; keep it minimal and avoid production-only test hooks if component traversal can exercise enough behavior. + - Add a test that clicking the feedback button creates/shows popup content, if feasible in `BasePlatformTestCase`; otherwise test the retained popup content builder/action rows directly through package-internal methods. + - Assert the three action labels exist and URL callbacks map to the same URLs as VS Code. + - Assert the Discord action has an icon, so the plan cannot regress to a text-only Discord row. + +5. Add release note. + - This is user-facing for the JetBrains plugin, so add a patch changeset under `.changeset/` unless the repo has a JetBrains-specific release-note mechanism that supersedes changesets. + - Suggested text: `Add Feedback & Support to the JetBrains empty session screen.` + +6. Verify. + - Run the focused frontend/JetBrains tests first, preferably from `packages/kilo-jetbrains/`: + - `./gradlew :frontend:test --tests "ai.kilocode.client.session.ui.EmptySessionPanelTest"` + - Run JetBrains typecheck from `packages/kilo-jetbrains/`: + - `bun run typecheck` or `./gradlew typecheck` + - If touching only frontend UI and tests pass, no backend/SDK generation is needed. + +## Notes + +- Do not add Kotlin UI DSL, Compose, or JCEF. +- Do not modify shared opencode files; this work is entirely under `packages/kilo-jetbrains/` plus a changeset. +- Prefer platform icons where available, but explicitly borrow/add the Discord icon because `AllIcons` does not provide one and the popup should match the VS Code button set visually. diff --git a/bun.lock b/bun.lock index 3938c57547f..a921861a7d9 100644 --- a/bun.lock +++ b/bun.lock @@ -85,6 +85,7 @@ "dependencies": { "@kilocode/kilo-web-ui": "workspace:*", "@kilocode/sdk": "workspace:*", + "@lottiefiles/dotlottie-web": "0.74.0", "@opencode-ai/ui": "workspace:*", "@solidjs/router": "catalog:", "ghostty-web": "0.4.0", @@ -1354,6 +1355,8 @@ "@leichtgewicht/ip-codec": ["@leichtgewicht/ip-codec@2.0.5", "", {}, "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw=="], + "@lottiefiles/dotlottie-web": ["@lottiefiles/dotlottie-web@0.74.0", "", {}, "sha512-rG12+dJSVhQDdleGr9epR7zU/UJ6hh8jzBDHAurClHP5t5dSrOh3eP3UCFxolpVPcobaRVYsBnYg4HQokQewpg=="], + "@lukeed/ms": ["@lukeed/ms@2.0.2", "", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="], "@lydell/node-pty": ["@lydell/node-pty@1.2.0-beta.10", "", { "optionalDependencies": { "@lydell/node-pty-darwin-arm64": "1.2.0-beta.10", "@lydell/node-pty-darwin-x64": "1.2.0-beta.10", "@lydell/node-pty-linux-arm64": "1.2.0-beta.10", "@lydell/node-pty-linux-x64": "1.2.0-beta.10", "@lydell/node-pty-win32-arm64": "1.2.0-beta.10", "@lydell/node-pty-win32-x64": "1.2.0-beta.10" } }, "sha512-Fv+A3+MZVA8qhkBIZsM1E6dCdHNMyXXz22mAYiMWd03LlyK///F3OH6CKPX9mj4id7LUlxpr45yPzyBVy9aDPw=="], diff --git a/nix/hashes.json b/nix/hashes.json index db617d736bd..c120a3334f6 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-STfDdoDiRwXnQ3B8lueNSZp4iJFL9TAME6R+dnxI1eU=", - "aarch64-linux": "sha256-v/N0eCo1pa3n5QTMdLHBYICIEdI0BiNEsMzgRbOEXfA=", - "aarch64-darwin": "sha256-gC6iPlR+UTo336ukkHIzHKQMwxFOdyTIl9UCIh/XVdw=", - "x86_64-darwin": "sha256-es6bcIwldn0sKHnC7TqOaL+IST3zZ3JrHbH8ojGbQQ0=" + "x86_64-linux": "sha256-b1eputqQyEDXT8LRZcGtx31TLm9wjUHHPJ8IivkPihY=", + "aarch64-linux": "sha256-0FGGe2pztqcWcMw1Ie+QlNTmJv0VM7vXTmCZ18M70hk=", + "aarch64-darwin": "sha256-McaXAipKk7yv2Ia1Py6Zp/WH2kDwRroy1/tnavbDYb4=", + "x86_64-darwin": "sha256-ARngNvK5UwQYZa5Uvx7o/cKWaQWY5/AlSXecX0UdtDM=" } } diff --git a/packages/kilo-console/package.json b/packages/kilo-console/package.json index 45539070c38..74cefc973bc 100644 --- a/packages/kilo-console/package.json +++ b/packages/kilo-console/package.json @@ -13,6 +13,7 @@ "dependencies": { "@kilocode/kilo-web-ui": "workspace:*", "@kilocode/sdk": "workspace:*", + "@lottiefiles/dotlottie-web": "0.74.0", "@opencode-ai/ui": "workspace:*", "@solidjs/router": "catalog:", "ghostty-web": "0.4.0", diff --git a/packages/kilo-console/public/logo.lottie b/packages/kilo-console/public/logo.lottie new file mode 100644 index 00000000000..d16c02faf11 Binary files /dev/null and b/packages/kilo-console/public/logo.lottie differ diff --git a/packages/kilo-console/src/components/LoadingLogo.tsx b/packages/kilo-console/src/components/LoadingLogo.tsx new file mode 100644 index 00000000000..6e261e69fab --- /dev/null +++ b/packages/kilo-console/src/components/LoadingLogo.tsx @@ -0,0 +1,34 @@ +import { DotLottie } from "@lottiefiles/dotlottie-web" +import { onCleanup, onMount } from "solid-js" + +const src = `${import.meta.env.BASE_URL}logo.lottie` + +export function LoadingLogo(props: { class?: string }) { + let canvas: HTMLCanvasElement | undefined + + onMount(() => { + if (!canvas) return + + const motion = !window.matchMedia("(prefers-reduced-motion: reduce)").matches + const player = new DotLottie({ + autoplay: motion, + canvas, + loop: motion, + src, + renderConfig: { + autoResize: true, + }, + }) + + onCleanup(() => player.destroy()) + }) + + return ( + (canvas = node)} + class={`console-loading-logo${props.class ? ` ${props.class}` : ""}`} + role="img" + aria-label="Kilo loading animation" + /> + ) +} diff --git a/packages/kilo-console/src/components/LoadingScreen.tsx b/packages/kilo-console/src/components/LoadingScreen.tsx new file mode 100644 index 00000000000..e1ffc181d0f --- /dev/null +++ b/packages/kilo-console/src/components/LoadingScreen.tsx @@ -0,0 +1,20 @@ +import { LoadingLogo } from "./LoadingLogo" + +type Variant = "fullscreen" | "content" + +export function LoadingScreen(props: { variant: Variant }) { + return ( +
+ +
+ ) +} diff --git a/packages/kilo-console/src/layouts/ConfigLayout.tsx b/packages/kilo-console/src/layouts/ConfigLayout.tsx index 09ce8141bd8..8f779b93283 100644 --- a/packages/kilo-console/src/layouts/ConfigLayout.tsx +++ b/packages/kilo-console/src/layouts/ConfigLayout.tsx @@ -1,6 +1,7 @@ import { Show } from "solid-js" import type { JSX } from "solid-js" import { Card } from "@kilocode/kilo-web-ui/card" +import { LoadingScreen } from "../components/LoadingScreen" import { ConfigProvider } from "../context/ConfigProvider" import { useConfig } from "../context/config" import { ConfigSidebar } from "../routes/config/ConfigSidebar" @@ -43,9 +44,7 @@ function ConfigContent(props: { children?: JSX.Element }) { - + {props.children} diff --git a/packages/kilo-console/src/routes/projects/ProjectConsoleRoute.tsx b/packages/kilo-console/src/routes/projects/ProjectConsoleRoute.tsx index 294b1ca2e07..7f576e7fb60 100644 --- a/packages/kilo-console/src/routes/projects/ProjectConsoleRoute.tsx +++ b/packages/kilo-console/src/routes/projects/ProjectConsoleRoute.tsx @@ -2,6 +2,7 @@ import { A, useLocation, useParams } from "@solidjs/router" import { createEffect, createMemo, createResource, createSignal, For, onCleanup, Show } from "solid-js" import { Card } from "@kilocode/kilo-web-ui/card" import { Icon } from "@kilocode/kilo-web-ui/icon" +import { LoadingScreen } from "../../components/LoadingScreen" import { createProjectPty, createProjectWorktree, @@ -677,14 +678,10 @@ export function ProjectConsoleRoute() {
- + - +