diff --git a/.gitattributes b/.gitattributes index 51298ca8a81..453ae820fe8 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,3 +4,4 @@ # Visual regression baseline snapshots packages/kilo-ui/tests/**/*.png filter=lfs diff=lfs merge=lfs -text +packages/kilo-vscode/tests/**/*.png filter=lfs diff=lfs merge=lfs -text diff --git a/.github/workflows/visual-regression.yml b/.github/workflows/visual-regression.yml index d764fd30543..4d23526c065 100644 --- a/.github/workflows/visual-regression.yml +++ b/.github/workflows/visual-regression.yml @@ -7,6 +7,9 @@ on: - "packages/ui/**" - "packages/util/**" - "packages/sdk/js/**" + - "packages/kilo-vscode/webview-ui/**" + - "packages/kilo-vscode/.storybook/**" + - "packages/kilo-vscode/tests/visual-regression*" - ".github/workflows/visual-regression.yml" jobs: @@ -101,3 +104,95 @@ jobs: name: visual-regression-results path: packages/kilo-ui/test-results/ retention-days: 7 + + visual-regression-vscode: + name: Visual Regression (kilo-vscode webview) + runs-on: blacksmith-4vcpu-ubuntu-2404 + timeout-minutes: 15 + + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + lfs: true + token: ${{ secrets.GITHUB_TOKEN }} + ref: ${{ github.head_ref }} + + - name: Setup Bun + uses: oven-sh/setup-bun@v2 + with: + bun-version: latest + + - name: Cache Bun modules + uses: actions/cache@v4 + with: + path: ~/.bun/install/cache + key: bun-${{ hashFiles('bun.lock') }} + + - name: Install dependencies + run: bun install + + - name: Cache Playwright browsers + id: playwright-cache-vscode + uses: actions/cache@v4 + with: + path: ~/.cache/ms-playwright + key: playwright-vscode-${{ hashFiles('packages/kilo-vscode/package.json') }} + + - name: Install Playwright browsers + if: steps.playwright-cache-vscode.outputs.cache-hit != 'true' + run: bunx playwright install chromium + working-directory: packages/kilo-vscode + + - name: Install Playwright system deps + run: bunx playwright install-deps chromium + working-directory: packages/kilo-vscode + + - name: Cache Storybook build + id: storybook-cache-vscode + uses: actions/cache@v4 + with: + path: packages/kilo-vscode/storybook-static + key: storybook-vscode-${{ hashFiles('packages/kilo-vscode/webview-ui/src/**', 'packages/kilo-vscode/.storybook/**', 'packages/kilo-ui/src/**', 'packages/ui/src/**', 'packages/kilo-vscode/package.json') }} + + - name: Build Storybook + if: steps.storybook-cache-vscode.outputs.cache-hit != 'true' + run: bun run build-storybook + working-directory: packages/kilo-vscode + + - name: Generate baselines for new/missing stories + run: bun run test:visual:update + working-directory: packages/kilo-vscode + env: + CI: true + PLAYWRIGHT_WORKERS: "4" + + - name: Commit and push new baselines (if any) + id: commit-baselines-vscode + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/ + if git diff --cached --quiet; then + echo "No new baselines — nothing to commit." + echo "changed=false" >> "$GITHUB_OUTPUT" + else + git commit -m "chore: update kilo-vscode visual regression baselines" + git lfs push --all origin + git push + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Fail if baselines changed + if: steps.commit-baselines-vscode.outputs.changed == 'true' + run: | + echo "::error::Visual regression baselines changed. New baselines have been committed to the branch. Please pull and review." + exit 1 + + - name: Upload test results on failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: visual-regression-vscode-results + path: packages/kilo-vscode/test-results/ + retention-days: 7 diff --git a/.gitignore b/.gitignore index b678f695639..6bd9245c08b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.husky/_ .DS_Store node_modules .worktrees diff --git a/bun.lock b/bun.lock index d6cbe107013..b83407285a6 100644 --- a/bun.lock +++ b/bun.lock @@ -25,7 +25,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@kilocode/kilo-i18n": "workspace:*", "@kilocode/kilo-ui": "workspace:*", @@ -77,7 +77,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -110,7 +110,7 @@ }, "packages/kilo-docs": { "name": "@kilocode/kilo-docs", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@docsearch/css": "^4", "@docsearch/js": "^4", @@ -139,7 +139,7 @@ }, "packages/kilo-gateway": { "name": "@kilocode/kilo-gateway", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@clack/prompts": "1.0.0-alpha.1", "@kilocode/plugin": "workspace:*", @@ -171,7 +171,7 @@ }, "packages/kilo-i18n": { "name": "@kilocode/kilo-i18n", - "version": "7.0.36", + "version": "7.0.37", "devDependencies": { "@tsconfig/node22": "catalog:", "@types/bun": "catalog:", @@ -181,7 +181,7 @@ }, "packages/kilo-telemetry": { "name": "@kilocode/kilo-telemetry", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@kilocode/kilo-gateway": "workspace:*", "@opentelemetry/api": "1.9.0", @@ -201,7 +201,7 @@ }, "packages/kilo-ui": { "name": "@kilocode/kilo-ui", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@kobalte/core": "0.13.11", "lucide-solid": "0.576.0", @@ -226,7 +226,7 @@ }, "packages/kilo-vscode": { "name": "kilo-code", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@anthropic-ai/sdk": "^0.39.0", "@kilocode/kilo-i18n": "workspace:*", @@ -249,6 +249,8 @@ "zod": "^3.24.2", }, "devDependencies": { + "@playwright/test": "1.58.2", + "@storybook/addon-docs": "10.2.10", "@types/diff": "^6.0.0", "@types/mocha": "^10.0.10", "@types/node": "22.x", @@ -263,14 +265,18 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.8.1", "qrcode": "^1.5.4", + "storybook": "10.2.10", + "storybook-solidjs-vite": "10.0.9", "ts-morph": "27.0.2", "typescript": "^5.9.3", "typescript-eslint": "^8.54.0", + "vite": "7.3.1", + "vite-plugin-solid": "2.11.10", }, }, "packages/opencode": { "name": "@kilocode/cli", - "version": "7.0.36", + "version": "7.0.37", "bin": { "opencode": "./bin/opencode", }, @@ -387,7 +393,7 @@ }, "packages/plugin": { "name": "@kilocode/plugin", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@kilocode/sdk": "workspace:*", "zod": "catalog:", @@ -401,14 +407,14 @@ }, "packages/script": { "name": "@opencode-ai/script", - "version": "7.0.36", + "version": "7.0.37", "devDependencies": { "@types/bun": "catalog:", }, }, "packages/sdk/js": { "name": "@kilocode/sdk", - "version": "7.0.36", + "version": "7.0.37", "devDependencies": { "@hey-api/openapi-ts": "0.90.10", "@tsconfig/node22": "catalog:", @@ -419,7 +425,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", @@ -461,7 +467,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "7.0.36", + "version": "7.0.37", "dependencies": { "zod": "catalog:", }, diff --git a/nix/hashes.json b/nix/hashes.json index 847be80aa1a..745efd12c5a 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-NrbWpaXEMxKRZVMwSfn0Zt/iJ+/rAgdkeu8saQtPJWg=", - "aarch64-linux": "sha256-qwV7BBySUF2NpgFpPrYUAyEcOKOEHu0Su9HiDIoGlYk=", - "aarch64-darwin": "sha256-eHGuncX+swJvE3UNKCl6yy9AeWHMkpZK209oEsCOjnc=", - "x86_64-darwin": "sha256-jMqI1kJ/QVzPaOO8cVmm5dh5MFYSJ7YMkyAifgBO9KA=" + "x86_64-linux": "sha256-7YoMJRkLfE+49GuItkoTLj1nk8CxLAHGIdRtH2L5n4w=", + "aarch64-linux": "sha256-A+JUa7PI+ICd1+xCzQM11zZQMzsOWYFwULTo7sk4t5Q=", + "aarch64-darwin": "sha256-Pbh4id/Crsy6s6J2s7QlbDnUwtsdUXGjt+K5qz7o1mU=", + "x86_64-darwin": "sha256-hSdwk2LNlSr25p4YKb5Yh4K3L0CazFQ+SOXIfFY0jCY=" } } diff --git a/package.json b/package.json index 58e7769a6b2..31d0d8f4678 100644 --- a/package.json +++ b/package.json @@ -107,6 +107,6 @@ "@openrouter/ai-sdk-provider@1.5.4": "patches/@openrouter%2Fai-sdk-provider@1.5.4.patch", "ghostty-web@0.3.0": "patches/ghostty-web@0.3.0.patch" }, - "version": "7.0.36", + "version": "7.0.37", "peerDependencies": {} } diff --git a/packages/app/package.json b/packages/app/package.json index 52008cbd6a1..66bb1d50cf6 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "7.0.36", + "version": "7.0.37", "description": "", "type": "module", "exports": { diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 52fe5424607..b1242ed1eba 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index c3acdaeab1d..43a6c816c15 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "kilo" name = "Kilo" description = "The open source coding agent." -version = "7.0.36" +version = "7.0.37" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/Kilo-Org/kilocode" @@ -11,26 +11,26 @@ name = "Kilo" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.36/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.37/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.36/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.37/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.36/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.37/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.36/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.37/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.36/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.37/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/kilo-docs/components/TopNav.tsx b/packages/kilo-docs/components/TopNav.tsx index ca41fbb7bfd..dbc0d077d3c 100644 --- a/packages/kilo-docs/components/TopNav.tsx +++ b/packages/kilo-docs/components/TopNav.tsx @@ -529,12 +529,12 @@ export function TopNav({ onMobileMenuToggle, isMobileMenuOpen = false, showMobil } .announcement-banner { - background: #1a1a18; - color: #a3a3a2; + background: var(--bg-secondary); + color: var(--text-color); padding: 0.5rem 1rem; text-align: center; font-size: 0.875rem; - border-bottom: 1px solid #3f3f3f; + border-bottom: 1px solid var(--border-color); } .announcement-banner p { @@ -542,13 +542,13 @@ export function TopNav({ onMobileMenuToggle, isMobileMenuOpen = false, showMobil } .announcement-banner :global(a) { - color: #f8f674; + color: var(--accent-color); text-decoration: underline; text-underline-offset: 2px; } .announcement-banner :global(a:hover) { - color: #ffff8d; + color: var(--accent-hover); } @media (max-width: 768px) { diff --git a/packages/kilo-docs/package.json b/packages/kilo-docs/package.json index 11f515eddb4..74ca7116320 100644 --- a/packages/kilo-docs/package.json +++ b/packages/kilo-docs/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-docs", - "version": "7.0.36", + "version": "7.0.37", "private": true, "scripts": { "dev": "next dev --webpack --port 3002", diff --git a/packages/kilo-gateway/package.json b/packages/kilo-gateway/package.json index bcd1c8d71f7..6fcdabb6d24 100644 --- a/packages/kilo-gateway/package.json +++ b/packages/kilo-gateway/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-gateway", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration", diff --git a/packages/kilo-gateway/src/api/constants.ts b/packages/kilo-gateway/src/api/constants.ts index a10781e6b49..fb32b041a6f 100644 --- a/packages/kilo-gateway/src/api/constants.ts +++ b/packages/kilo-gateway/src/api/constants.ts @@ -58,13 +58,14 @@ export const DEFAULT_EDITOR_NAME = "Kilo CLI" /** Environment variable name for custom editor name */ export const ENV_EDITOR_NAME = "KILOCODE_EDITOR_NAME" +/** Environment variable name for version (set by CLI at startup) */ +export const ENV_VERSION = "KILOCODE_VERSION" + /** Tester header value for suppressing warnings */ export const TESTER_SUPPRESS_VALUE = "SUPPRESS" -// kilocode_change start /** Header name for feature tracking */ export const HEADER_FEATURE = "X-KILOCODE-FEATURE" /** Environment variable name for feature override */ export const ENV_FEATURE = "KILOCODE_FEATURE" -// kilocode_change end diff --git a/packages/kilo-gateway/src/api/notifications.ts b/packages/kilo-gateway/src/api/notifications.ts index 2d0994e94bd..286686717eb 100644 --- a/packages/kilo-gateway/src/api/notifications.ts +++ b/packages/kilo-gateway/src/api/notifications.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import { z } from "zod" import { KILO_API_BASE } from "./constants.js" diff --git a/packages/kilo-gateway/src/auth/legacy-migration.ts b/packages/kilo-gateway/src/auth/legacy-migration.ts index 1f53feb66d7..34944dbfb0d 100644 --- a/packages/kilo-gateway/src/auth/legacy-migration.ts +++ b/packages/kilo-gateway/src/auth/legacy-migration.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file /** * Legacy Kilo CLI migration module * diff --git a/packages/kilo-gateway/src/headers.ts b/packages/kilo-gateway/src/headers.ts index c9767f3e1f8..6170c427e7e 100644 --- a/packages/kilo-gateway/src/headers.ts +++ b/packages/kilo-gateway/src/headers.ts @@ -10,8 +10,9 @@ import { CONTENT_TYPE, DEFAULT_EDITOR_NAME, ENV_EDITOR_NAME, + ENV_VERSION, TESTER_SUPPRESS_VALUE, - ENV_FEATURE, // kilocode_change + ENV_FEATURE, } from "./api/constants.js" /** @@ -45,10 +46,13 @@ export const DEFAULT_HEADERS = { /** * Get editor name header value - * Defaults to "opencode" but can be customized + * Defaults to "Kilo CLI" but can be customized via KILOCODE_EDITOR_NAME. + * Appends the version from KILOCODE_VERSION when available. */ export function getEditorNameHeader(): string { - return process.env[ENV_EDITOR_NAME] ?? DEFAULT_EDITOR_NAME + const name = process.env[ENV_EDITOR_NAME] ?? DEFAULT_EDITOR_NAME + const version = process.env[ENV_VERSION] + return version ? `${name} ${version}` : name } /** @@ -62,13 +66,11 @@ export function buildKiloHeaders( machineId?: string }, ): Record { - // kilocode_change start const feature = getFeatureHeader() const headers: Record = { [X_KILOCODE_EDITORNAME]: getEditorNameHeader(), ...(feature ? { [X_KILOCODE_FEATURE]: feature } : {}), } - // kilocode_change end if (metadata?.taskId) { headers[X_KILOCODE_TASKID] = metadata.taskId diff --git a/packages/kilo-gateway/src/index.ts b/packages/kilo-gateway/src/index.ts index 9f10c75fb07..c2c2325ad59 100644 --- a/packages/kilo-gateway/src/index.ts +++ b/packages/kilo-gateway/src/index.ts @@ -9,7 +9,7 @@ export { KiloAuthPlugin, default } from "./plugin.js" export { createKilo } from "./provider.js" export { createKiloDebug } from "./provider-debug.js" export { kiloCustomLoader } from "./loader.js" -export { buildKiloHeaders, getEditorNameHeader, getFeatureHeader, DEFAULT_HEADERS } from "./headers.js" // kilocode_change - added getFeatureHeader +export { buildKiloHeaders, getEditorNameHeader, getFeatureHeader, DEFAULT_HEADERS } from "./headers.js" // ============================================================================ // Auth @@ -93,6 +93,7 @@ export { HEADER_FEATURE, DEFAULT_EDITOR_NAME, ENV_EDITOR_NAME, + ENV_VERSION, TESTER_SUPPRESS_VALUE, ENV_FEATURE, } from "./api/constants.js" diff --git a/packages/kilo-gateway/src/types.ts b/packages/kilo-gateway/src/types.ts index d61c598f0d1..5afecffe09d 100644 --- a/packages/kilo-gateway/src/types.ts +++ b/packages/kilo-gateway/src/types.ts @@ -1,4 +1,3 @@ -// kilocode_change - Kilo Gateway types import type { Provider as SDK } from "ai" import type { LanguageModelV2 } from "@openrouter/ai-sdk-provider" diff --git a/packages/kilo-i18n/package.json b/packages/kilo-i18n/package.json index e5196316760..112872239ad 100644 --- a/packages/kilo-i18n/package.json +++ b/packages/kilo-i18n/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-i18n", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "description": "Kilo-specific i18n translations and overrides", diff --git a/packages/kilo-i18n/src/ar.ts b/packages/kilo-i18n/src/ar.ts index 27963894dcc..4a8cd1c79ff 100644 --- a/packages/kilo-i18n/src/ar.ts +++ b/packages/kilo-i18n/src/ar.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/br.ts b/packages/kilo-i18n/src/br.ts index 5ac4369243e..4734a98d0f4 100644 --- a/packages/kilo-i18n/src/br.ts +++ b/packages/kilo-i18n/src/br.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/bs.ts b/packages/kilo-i18n/src/bs.ts index e1400fc227c..28025010251 100644 --- a/packages/kilo-i18n/src/bs.ts +++ b/packages/kilo-i18n/src/bs.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/da.ts b/packages/kilo-i18n/src/da.ts index d5c89a5bf4d..16f0c8f6828 100644 --- a/packages/kilo-i18n/src/da.ts +++ b/packages/kilo-i18n/src/da.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/de.ts b/packages/kilo-i18n/src/de.ts index 97c12ef614a..b39b7eb4776 100644 --- a/packages/kilo-i18n/src/de.ts +++ b/packages/kilo-i18n/src/de.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/en.ts b/packages/kilo-i18n/src/en.ts index 237a635c751..070c3d41cea 100644 --- a/packages/kilo-i18n/src/en.ts +++ b/packages/kilo-i18n/src/en.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file // Kilo-specific translations and overrides // Keys here will override any matching keys from upstream translations export const dict = { diff --git a/packages/kilo-i18n/src/es.ts b/packages/kilo-i18n/src/es.ts index 59165915854..25c5dba9f36 100644 --- a/packages/kilo-i18n/src/es.ts +++ b/packages/kilo-i18n/src/es.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/fr.ts b/packages/kilo-i18n/src/fr.ts index 513ffc6ba1f..d593e4a2be3 100644 --- a/packages/kilo-i18n/src/fr.ts +++ b/packages/kilo-i18n/src/fr.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/ja.ts b/packages/kilo-i18n/src/ja.ts index 676550a67e4..08eda7545aa 100644 --- a/packages/kilo-i18n/src/ja.ts +++ b/packages/kilo-i18n/src/ja.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/ko.ts b/packages/kilo-i18n/src/ko.ts index 0f76b05155b..cbbd28aa1f3 100644 --- a/packages/kilo-i18n/src/ko.ts +++ b/packages/kilo-i18n/src/ko.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/no.ts b/packages/kilo-i18n/src/no.ts index 3d6ede4b4b5..bd17fff9b59 100644 --- a/packages/kilo-i18n/src/no.ts +++ b/packages/kilo-i18n/src/no.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/pl.ts b/packages/kilo-i18n/src/pl.ts index 327317ebb49..63aea01e6e3 100644 --- a/packages/kilo-i18n/src/pl.ts +++ b/packages/kilo-i18n/src/pl.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/ru.ts b/packages/kilo-i18n/src/ru.ts index 182652dced8..7a0276ad710 100644 --- a/packages/kilo-i18n/src/ru.ts +++ b/packages/kilo-i18n/src/ru.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/th.ts b/packages/kilo-i18n/src/th.ts index eaef9b0bde9..d6f88c10b10 100644 --- a/packages/kilo-i18n/src/th.ts +++ b/packages/kilo-i18n/src/th.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": diff --git a/packages/kilo-i18n/src/zh.ts b/packages/kilo-i18n/src/zh.ts index 6cbf5301ab3..93d0f4f6c0d 100644 --- a/packages/kilo-i18n/src/zh.ts +++ b/packages/kilo-i18n/src/zh.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": "Kilo Gateway 为您提供一组精选的可靠优化模型,专为编码代理设计。", diff --git a/packages/kilo-i18n/src/zht.ts b/packages/kilo-i18n/src/zht.ts index 69f93085439..a5b9a019f62 100644 --- a/packages/kilo-i18n/src/zht.ts +++ b/packages/kilo-i18n/src/zht.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export const dict = { // Kilo Gateway provider translations "provider.connect.kiloGateway.line1": "Kilo Gateway 為您提供一組精選的可靠優化模型,專為編碼代理設計。", diff --git a/packages/kilo-telemetry/package.json b/packages/kilo-telemetry/package.json index e535eacea81..67b125fee70 100644 --- a/packages/kilo-telemetry/package.json +++ b/packages/kilo-telemetry/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-telemetry", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "description": "Telemetry for Kilo CLI - PostHog analytics integration", diff --git a/packages/kilo-ui/package.json b/packages/kilo-ui/package.json index 955396a36aa..e8be7458173 100644 --- a/packages/kilo-ui/package.json +++ b/packages/kilo-ui/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-ui", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "exports": { diff --git a/packages/kilo-ui/src/components/accordion.css b/packages/kilo-ui/src/components/accordion.css index d7c70c5840a..aa522a7131f 100644 --- a/packages/kilo-ui/src/components/accordion.css +++ b/packages/kilo-ui/src/components/accordion.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Accordion overrides */ [data-component="accordion"] { diff --git a/packages/kilo-ui/src/components/accordion.tsx b/packages/kilo-ui/src/components/accordion.tsx index 24a9358ff78..5eac74c261a 100644 --- a/packages/kilo-ui/src/components/accordion.tsx +++ b/packages/kilo-ui/src/components/accordion.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/accordion" diff --git a/packages/kilo-ui/src/components/app-icon.tsx b/packages/kilo-ui/src/components/app-icon.tsx index 80de2ede11a..6ab39549824 100644 --- a/packages/kilo-ui/src/components/app-icon.tsx +++ b/packages/kilo-ui/src/components/app-icon.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/app-icon" diff --git a/packages/kilo-ui/src/components/app-icons/types.ts b/packages/kilo-ui/src/components/app-icons/types.ts index 0654a12f8fb..fe900620fc6 100644 --- a/packages/kilo-ui/src/components/app-icons/types.ts +++ b/packages/kilo-ui/src/components/app-icons/types.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/icons/app" diff --git a/packages/kilo-ui/src/components/auto-approve-bar.css b/packages/kilo-ui/src/components/auto-approve-bar.css index 14aa6a8fc19..517e05d0846 100644 --- a/packages/kilo-ui/src/components/auto-approve-bar.css +++ b/packages/kilo-ui/src/components/auto-approve-bar.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Auto-approve Bar overrides */ [data-component="auto-approve-bar"] { diff --git a/packages/kilo-ui/src/components/avatar.tsx b/packages/kilo-ui/src/components/avatar.tsx index 3deb6c05d66..1de760ad7ab 100644 --- a/packages/kilo-ui/src/components/avatar.tsx +++ b/packages/kilo-ui/src/components/avatar.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/avatar" diff --git a/packages/kilo-ui/src/components/basic-tool.css b/packages/kilo-ui/src/components/basic-tool.css index f440dd42da1..7891116b576 100644 --- a/packages/kilo-ui/src/components/basic-tool.css +++ b/packages/kilo-ui/src/components/basic-tool.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Prevent tool-trigger content from pushing the collapsible arrow off-screen */ [data-component="tool-trigger"] { [data-slot="basic-tool-tool-trigger-content"] { diff --git a/packages/kilo-ui/src/components/basic-tool.tsx b/packages/kilo-ui/src/components/basic-tool.tsx index 36c4fb31f42..66d15277b35 100644 --- a/packages/kilo-ui/src/components/basic-tool.tsx +++ b/packages/kilo-ui/src/components/basic-tool.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/basic-tool" diff --git a/packages/kilo-ui/src/components/button.css b/packages/kilo-ui/src/components/button.css index 09fc5c1a8ce..2aa86b2078c 100644 --- a/packages/kilo-ui/src/components/button.css +++ b/packages/kilo-ui/src/components/button.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Button overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="button"] { diff --git a/packages/kilo-ui/src/components/button.tsx b/packages/kilo-ui/src/components/button.tsx index 780a9fffc2d..2623a711ca1 100644 --- a/packages/kilo-ui/src/components/button.tsx +++ b/packages/kilo-ui/src/components/button.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/button" diff --git a/packages/kilo-ui/src/components/card.css b/packages/kilo-ui/src/components/card.css index 3bfd65c7787..7e97fcf316a 100644 --- a/packages/kilo-ui/src/components/card.css +++ b/packages/kilo-ui/src/components/card.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Card overrides – harmonized with @vscode/webview-ui-toolkit */ [data-component="card"] { diff --git a/packages/kilo-ui/src/components/card.tsx b/packages/kilo-ui/src/components/card.tsx index f94fc8a57ed..e023f2946d2 100644 --- a/packages/kilo-ui/src/components/card.tsx +++ b/packages/kilo-ui/src/components/card.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/card" diff --git a/packages/kilo-ui/src/components/chat-input.css b/packages/kilo-ui/src/components/chat-input.css index 6761767332c..bfd29fc7028 100644 --- a/packages/kilo-ui/src/components/chat-input.css +++ b/packages/kilo-ui/src/components/chat-input.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Chat Input (Textarea with blue border) overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="chat-input"], diff --git a/packages/kilo-ui/src/components/checkbox.css b/packages/kilo-ui/src/components/checkbox.css index a39f431419d..cde6fa89b6e 100644 --- a/packages/kilo-ui/src/components/checkbox.css +++ b/packages/kilo-ui/src/components/checkbox.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Checkbox overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="checkbox"] { diff --git a/packages/kilo-ui/src/components/checkbox.tsx b/packages/kilo-ui/src/components/checkbox.tsx index b7645e7afa3..0338fe0c530 100644 --- a/packages/kilo-ui/src/components/checkbox.tsx +++ b/packages/kilo-ui/src/components/checkbox.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/checkbox" diff --git a/packages/kilo-ui/src/components/code.css b/packages/kilo-ui/src/components/code.css index a43012f109b..bfde26a279d 100644 --- a/packages/kilo-ui/src/components/code.css +++ b/packages/kilo-ui/src/components/code.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Code overrides */ [data-component="code"] { diff --git a/packages/kilo-ui/src/components/code.tsx b/packages/kilo-ui/src/components/code.tsx index afc131525e0..40b98cd70ed 100644 --- a/packages/kilo-ui/src/components/code.tsx +++ b/packages/kilo-ui/src/components/code.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/code" diff --git a/packages/kilo-ui/src/components/collapsible.tsx b/packages/kilo-ui/src/components/collapsible.tsx index 019afa844f5..190f3a16cd3 100644 --- a/packages/kilo-ui/src/components/collapsible.tsx +++ b/packages/kilo-ui/src/components/collapsible.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/collapsible" diff --git a/packages/kilo-ui/src/components/context-menu.css b/packages/kilo-ui/src/components/context-menu.css index 72d5402ab63..feeefc704c1 100644 --- a/packages/kilo-ui/src/components/context-menu.css +++ b/packages/kilo-ui/src/components/context-menu.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Context Menu overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="context-menu-content"], diff --git a/packages/kilo-ui/src/components/context-menu.tsx b/packages/kilo-ui/src/components/context-menu.tsx index 8ab04ce1109..6657036b236 100644 --- a/packages/kilo-ui/src/components/context-menu.tsx +++ b/packages/kilo-ui/src/components/context-menu.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context-menu" diff --git a/packages/kilo-ui/src/components/dialog.css b/packages/kilo-ui/src/components/dialog.css index e571f5cc7f8..742cd1690d7 100644 --- a/packages/kilo-ui/src/components/dialog.css +++ b/packages/kilo-ui/src/components/dialog.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Dialog overrides – harmonized with @vscode/webview-ui-toolkit */ [data-component="dialog-overlay"] { diff --git a/packages/kilo-ui/src/components/dialog.tsx b/packages/kilo-ui/src/components/dialog.tsx index 69329dcae3a..078bb487e82 100644 --- a/packages/kilo-ui/src/components/dialog.tsx +++ b/packages/kilo-ui/src/components/dialog.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/dialog" diff --git a/packages/kilo-ui/src/components/diff-changes.tsx b/packages/kilo-ui/src/components/diff-changes.tsx index 03b78b6fc43..a0c85321530 100644 --- a/packages/kilo-ui/src/components/diff-changes.tsx +++ b/packages/kilo-ui/src/components/diff-changes.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/diff-changes" diff --git a/packages/kilo-ui/src/components/diff-ssr.tsx b/packages/kilo-ui/src/components/diff-ssr.tsx index 6c99dd6dd2d..1c8c7f2dc79 100644 --- a/packages/kilo-ui/src/components/diff-ssr.tsx +++ b/packages/kilo-ui/src/components/diff-ssr.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/diff-ssr" diff --git a/packages/kilo-ui/src/components/diff.tsx b/packages/kilo-ui/src/components/diff.tsx index 5f5cfa6ab0d..256d5495f57 100644 --- a/packages/kilo-ui/src/components/diff.tsx +++ b/packages/kilo-ui/src/components/diff.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/diff" diff --git a/packages/kilo-ui/src/components/dock-prompt.tsx b/packages/kilo-ui/src/components/dock-prompt.tsx index b298a9de0f4..696987ecc56 100644 --- a/packages/kilo-ui/src/components/dock-prompt.tsx +++ b/packages/kilo-ui/src/components/dock-prompt.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/dock-prompt" diff --git a/packages/kilo-ui/src/components/dock-surface.tsx b/packages/kilo-ui/src/components/dock-surface.tsx index 926b78cb5bd..b8f4ae1a5a6 100644 --- a/packages/kilo-ui/src/components/dock-surface.tsx +++ b/packages/kilo-ui/src/components/dock-surface.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/dock-surface" diff --git a/packages/kilo-ui/src/components/dropdown-menu.css b/packages/kilo-ui/src/components/dropdown-menu.css index efda95ad8f3..00901bdca45 100644 --- a/packages/kilo-ui/src/components/dropdown-menu.css +++ b/packages/kilo-ui/src/components/dropdown-menu.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Dropdown Menu overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="dropdown-menu-content"], @@ -21,12 +20,10 @@ color: var(--text-on-interactive-base, var(--text-strong)); } - /* kilocode_change start - preserve disabled state behavior from upstream */ &[data-disabled] { cursor: default; pointer-events: none; } - /* kilocode_change end */ } [data-slot="dropdown-menu-separator"] { diff --git a/packages/kilo-ui/src/components/dropdown-menu.tsx b/packages/kilo-ui/src/components/dropdown-menu.tsx index 6ba18963d4c..c20c829c47b 100644 --- a/packages/kilo-ui/src/components/dropdown-menu.tsx +++ b/packages/kilo-ui/src/components/dropdown-menu.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/dropdown-menu" diff --git a/packages/kilo-ui/src/components/favicon.tsx b/packages/kilo-ui/src/components/favicon.tsx index 14100f67bb2..a20f1586357 100644 --- a/packages/kilo-ui/src/components/favicon.tsx +++ b/packages/kilo-ui/src/components/favicon.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/favicon" diff --git a/packages/kilo-ui/src/components/file-icon.tsx b/packages/kilo-ui/src/components/file-icon.tsx index 94137149586..276f9c0bb83 100644 --- a/packages/kilo-ui/src/components/file-icon.tsx +++ b/packages/kilo-ui/src/components/file-icon.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/file-icon" diff --git a/packages/kilo-ui/src/components/file-icons/types.ts b/packages/kilo-ui/src/components/file-icons/types.ts index c04e859b953..3418f374888 100644 --- a/packages/kilo-ui/src/components/file-icons/types.ts +++ b/packages/kilo-ui/src/components/file-icons/types.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/icons/file-type" diff --git a/packages/kilo-ui/src/components/font.tsx b/packages/kilo-ui/src/components/font.tsx index 00973f31ce6..f2664c6e18a 100644 --- a/packages/kilo-ui/src/components/font.tsx +++ b/packages/kilo-ui/src/components/font.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/font" diff --git a/packages/kilo-ui/src/components/hover-card.tsx b/packages/kilo-ui/src/components/hover-card.tsx index 00abe9c09fb..e099c0bc298 100644 --- a/packages/kilo-ui/src/components/hover-card.tsx +++ b/packages/kilo-ui/src/components/hover-card.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/hover-card" diff --git a/packages/kilo-ui/src/components/icon-button.css b/packages/kilo-ui/src/components/icon-button.css index 3c971819876..6a0a08cfe02 100644 --- a/packages/kilo-ui/src/components/icon-button.css +++ b/packages/kilo-ui/src/components/icon-button.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Icon Button overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="icon-button"] { diff --git a/packages/kilo-ui/src/components/icon-button.tsx b/packages/kilo-ui/src/components/icon-button.tsx index bcfc87d4699..52c1b666f8d 100644 --- a/packages/kilo-ui/src/components/icon-button.tsx +++ b/packages/kilo-ui/src/components/icon-button.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/icon-button" diff --git a/packages/kilo-ui/src/components/icon.tsx b/packages/kilo-ui/src/components/icon.tsx index d24cf0e8dfc..90f437ca620 100644 --- a/packages/kilo-ui/src/components/icon.tsx +++ b/packages/kilo-ui/src/components/icon.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/icon" diff --git a/packages/kilo-ui/src/components/image-preview.tsx b/packages/kilo-ui/src/components/image-preview.tsx index 1fa59a41ea4..eefd941abe0 100644 --- a/packages/kilo-ui/src/components/image-preview.tsx +++ b/packages/kilo-ui/src/components/image-preview.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/image-preview" diff --git a/packages/kilo-ui/src/components/inline-input.css b/packages/kilo-ui/src/components/inline-input.css index 377383066fa..a17e6b354b6 100644 --- a/packages/kilo-ui/src/components/inline-input.css +++ b/packages/kilo-ui/src/components/inline-input.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Inline Input overrides */ [data-component="inline-input"] { diff --git a/packages/kilo-ui/src/components/inline-input.tsx b/packages/kilo-ui/src/components/inline-input.tsx index 1824fb0ce7a..8d92fb70b88 100644 --- a/packages/kilo-ui/src/components/inline-input.tsx +++ b/packages/kilo-ui/src/components/inline-input.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/inline-input" diff --git a/packages/kilo-ui/src/components/keybind.tsx b/packages/kilo-ui/src/components/keybind.tsx index 3a03af48f14..091a3c16e68 100644 --- a/packages/kilo-ui/src/components/keybind.tsx +++ b/packages/kilo-ui/src/components/keybind.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/keybind" diff --git a/packages/kilo-ui/src/components/line-comment.tsx b/packages/kilo-ui/src/components/line-comment.tsx index 439c6e9776e..5d778dfcbdf 100644 --- a/packages/kilo-ui/src/components/line-comment.tsx +++ b/packages/kilo-ui/src/components/line-comment.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/line-comment" diff --git a/packages/kilo-ui/src/components/list.css b/packages/kilo-ui/src/components/list.css index cdf44c888a3..8722cc81d89 100644 --- a/packages/kilo-ui/src/components/list.css +++ b/packages/kilo-ui/src/components/list.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo List overrides – styled to match legacy SelectDropdown items */ [data-component="list"] { diff --git a/packages/kilo-ui/src/components/list.tsx b/packages/kilo-ui/src/components/list.tsx index 1e52535838e..f0a09cf8a5d 100644 --- a/packages/kilo-ui/src/components/list.tsx +++ b/packages/kilo-ui/src/components/list.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/list" diff --git a/packages/kilo-ui/src/components/logo.tsx b/packages/kilo-ui/src/components/logo.tsx index 06ed609630a..05614ed1ecc 100644 --- a/packages/kilo-ui/src/components/logo.tsx +++ b/packages/kilo-ui/src/components/logo.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/logo" diff --git a/packages/kilo-ui/src/components/markdown.tsx b/packages/kilo-ui/src/components/markdown.tsx index 84fa665cd46..b40570c287f 100644 --- a/packages/kilo-ui/src/components/markdown.tsx +++ b/packages/kilo-ui/src/components/markdown.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/markdown" diff --git a/packages/kilo-ui/src/components/message-nav.tsx b/packages/kilo-ui/src/components/message-nav.tsx index 17321685d9b..71ae819e25a 100644 --- a/packages/kilo-ui/src/components/message-nav.tsx +++ b/packages/kilo-ui/src/components/message-nav.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/message-nav" diff --git a/packages/kilo-ui/src/components/message-part.css b/packages/kilo-ui/src/components/message-part.css index 83e43050307..063a52330f8 100644 --- a/packages/kilo-ui/src/components/message-part.css +++ b/packages/kilo-ui/src/components/message-part.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Message Part overrides */ [data-component="text-part"] { diff --git a/packages/kilo-ui/src/components/message-part.tsx b/packages/kilo-ui/src/components/message-part.tsx index a7dedd50c45..5b83670bb08 100644 --- a/packages/kilo-ui/src/components/message-part.tsx +++ b/packages/kilo-ui/src/components/message-part.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/message-part" diff --git a/packages/kilo-ui/src/components/message-row.css b/packages/kilo-ui/src/components/message-row.css index 7afdcf77847..57cb7bdd442 100644 --- a/packages/kilo-ui/src/components/message-row.css +++ b/packages/kilo-ui/src/components/message-row.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Message Row overrides */ [data-component="message-row"] { diff --git a/packages/kilo-ui/src/components/model-info-card.css b/packages/kilo-ui/src/components/model-info-card.css index 53f1aada78b..b8cd8c5bbd5 100644 --- a/packages/kilo-ui/src/components/model-info-card.css +++ b/packages/kilo-ui/src/components/model-info-card.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Model Info Card overrides – harmonized with @vscode/webview-ui-toolkit */ [data-component="model-info-card"] { diff --git a/packages/kilo-ui/src/components/model-selector.css b/packages/kilo-ui/src/components/model-selector.css index 1ba023e1ab4..89cf891532e 100644 --- a/packages/kilo-ui/src/components/model-selector.css +++ b/packages/kilo-ui/src/components/model-selector.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Model Selector Popover overrides – styled to match VSCode look */ /* ModelSelectorPopover content panel */ diff --git a/packages/kilo-ui/src/components/popover.css b/packages/kilo-ui/src/components/popover.css index e7f68707ef8..396a0b59923 100644 --- a/packages/kilo-ui/src/components/popover.css +++ b/packages/kilo-ui/src/components/popover.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Popover overrides */ [data-component="popover-content"] { diff --git a/packages/kilo-ui/src/components/popover.tsx b/packages/kilo-ui/src/components/popover.tsx index 9b39440d009..ce3ce7e577c 100644 --- a/packages/kilo-ui/src/components/popover.tsx +++ b/packages/kilo-ui/src/components/popover.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/popover" diff --git a/packages/kilo-ui/src/components/progress-circle.tsx b/packages/kilo-ui/src/components/progress-circle.tsx index 7407415ec9a..20e60f51f06 100644 --- a/packages/kilo-ui/src/components/progress-circle.tsx +++ b/packages/kilo-ui/src/components/progress-circle.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/progress-circle" diff --git a/packages/kilo-ui/src/components/prompt-input.css b/packages/kilo-ui/src/components/prompt-input.css index 1d258ae35d8..32c70da1939 100644 --- a/packages/kilo-ui/src/components/prompt-input.css +++ b/packages/kilo-ui/src/components/prompt-input.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Prompt Input overrides – styled to match legacy ChatTextArea look */ /* Form wrapper: VS Code native input look instead of pill shape */ diff --git a/packages/kilo-ui/src/components/provider-icon.tsx b/packages/kilo-ui/src/components/provider-icon.tsx index 0eea53f910e..da73096897e 100644 --- a/packages/kilo-ui/src/components/provider-icon.tsx +++ b/packages/kilo-ui/src/components/provider-icon.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/provider-icon" diff --git a/packages/kilo-ui/src/components/provider-icons/types.ts b/packages/kilo-ui/src/components/provider-icons/types.ts index bebc368086d..9aecae767db 100644 --- a/packages/kilo-ui/src/components/provider-icons/types.ts +++ b/packages/kilo-ui/src/components/provider-icons/types.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/icons/provider" diff --git a/packages/kilo-ui/src/components/radio-group.tsx b/packages/kilo-ui/src/components/radio-group.tsx index 8015b496f6e..89acd568698 100644 --- a/packages/kilo-ui/src/components/radio-group.tsx +++ b/packages/kilo-ui/src/components/radio-group.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/radio-group" diff --git a/packages/kilo-ui/src/components/resize-handle.tsx b/packages/kilo-ui/src/components/resize-handle.tsx index 39ae38b86ab..d6211237adb 100644 --- a/packages/kilo-ui/src/components/resize-handle.tsx +++ b/packages/kilo-ui/src/components/resize-handle.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/resize-handle" diff --git a/packages/kilo-ui/src/components/select.css b/packages/kilo-ui/src/components/select.css index b4a8f691609..006ebc262ca 100644 --- a/packages/kilo-ui/src/components/select.css +++ b/packages/kilo-ui/src/components/select.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Select overrides – styled to match legacy SelectDropdown look */ /* Select trigger (renders as a Button, override the button sizing) */ diff --git a/packages/kilo-ui/src/components/select.tsx b/packages/kilo-ui/src/components/select.tsx index 7b4aa81efde..d4a6c72f2cb 100644 --- a/packages/kilo-ui/src/components/select.tsx +++ b/packages/kilo-ui/src/components/select.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/select" diff --git a/packages/kilo-ui/src/components/session-review.tsx b/packages/kilo-ui/src/components/session-review.tsx index 32526449841..ae260216c3d 100644 --- a/packages/kilo-ui/src/components/session-review.tsx +++ b/packages/kilo-ui/src/components/session-review.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/session-review" diff --git a/packages/kilo-ui/src/components/session-turn.tsx b/packages/kilo-ui/src/components/session-turn.tsx index 842d3ac7e67..b267a716e2d 100644 --- a/packages/kilo-ui/src/components/session-turn.tsx +++ b/packages/kilo-ui/src/components/session-turn.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/session-turn" diff --git a/packages/kilo-ui/src/components/settings-sidebar.css b/packages/kilo-ui/src/components/settings-sidebar.css index aca96b92346..607da9661ae 100644 --- a/packages/kilo-ui/src/components/settings-sidebar.css +++ b/packages/kilo-ui/src/components/settings-sidebar.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Settings Sidebar overrides */ [data-component="settings-sidebar"] { diff --git a/packages/kilo-ui/src/components/spinner.tsx b/packages/kilo-ui/src/components/spinner.tsx index 8163d16dd56..8c2a5867558 100644 --- a/packages/kilo-ui/src/components/spinner.tsx +++ b/packages/kilo-ui/src/components/spinner.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/spinner" diff --git a/packages/kilo-ui/src/components/status-indicator.css b/packages/kilo-ui/src/components/status-indicator.css index 669dd7c43ba..b8bdfec65dd 100644 --- a/packages/kilo-ui/src/components/status-indicator.css +++ b/packages/kilo-ui/src/components/status-indicator.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Status Indicators overrides */ [data-component="status-indicator"] { diff --git a/packages/kilo-ui/src/components/sticky-accordion-header.tsx b/packages/kilo-ui/src/components/sticky-accordion-header.tsx index 697618deb59..a5cc4ce3949 100644 --- a/packages/kilo-ui/src/components/sticky-accordion-header.tsx +++ b/packages/kilo-ui/src/components/sticky-accordion-header.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/sticky-accordion-header" diff --git a/packages/kilo-ui/src/components/switch.css b/packages/kilo-ui/src/components/switch.css index c53d02b2079..3317a530b91 100644 --- a/packages/kilo-ui/src/components/switch.css +++ b/packages/kilo-ui/src/components/switch.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Switch overrides */ [data-component="switch"] { diff --git a/packages/kilo-ui/src/components/switch.tsx b/packages/kilo-ui/src/components/switch.tsx index d8277299d6f..ffdc396d7df 100644 --- a/packages/kilo-ui/src/components/switch.tsx +++ b/packages/kilo-ui/src/components/switch.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/switch" diff --git a/packages/kilo-ui/src/components/tabs.css b/packages/kilo-ui/src/components/tabs.css index e6065e6c4c6..15835b78760 100644 --- a/packages/kilo-ui/src/components/tabs.css +++ b/packages/kilo-ui/src/components/tabs.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Tabs overrides – sized to match @vscode/webview-ui-toolkit panels */ [data-component="tabs"] { diff --git a/packages/kilo-ui/src/components/tabs.tsx b/packages/kilo-ui/src/components/tabs.tsx index 38b5db328f6..f65d4ee49df 100644 --- a/packages/kilo-ui/src/components/tabs.tsx +++ b/packages/kilo-ui/src/components/tabs.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/tabs" diff --git a/packages/kilo-ui/src/components/tag.css b/packages/kilo-ui/src/components/tag.css index a3fb79d4841..416c7a08072 100644 --- a/packages/kilo-ui/src/components/tag.css +++ b/packages/kilo-ui/src/components/tag.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Tag (maps to legacy Badge) overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="tag"], diff --git a/packages/kilo-ui/src/components/tag.tsx b/packages/kilo-ui/src/components/tag.tsx index d88119b77de..7019bc03352 100644 --- a/packages/kilo-ui/src/components/tag.tsx +++ b/packages/kilo-ui/src/components/tag.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/tag" diff --git a/packages/kilo-ui/src/components/task-header.css b/packages/kilo-ui/src/components/task-header.css index e87afed2ff7..df7ddc96766 100644 --- a/packages/kilo-ui/src/components/task-header.css +++ b/packages/kilo-ui/src/components/task-header.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Task Header overrides */ [data-component="task-header"] { diff --git a/packages/kilo-ui/src/components/text-field.css b/packages/kilo-ui/src/components/text-field.css index 12be2757517..31f64c0ea89 100644 --- a/packages/kilo-ui/src/components/text-field.css +++ b/packages/kilo-ui/src/components/text-field.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Input / TextField overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="input"] { diff --git a/packages/kilo-ui/src/components/text-field.tsx b/packages/kilo-ui/src/components/text-field.tsx index dc94f876621..f99db50c3c1 100644 --- a/packages/kilo-ui/src/components/text-field.tsx +++ b/packages/kilo-ui/src/components/text-field.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/text-field" diff --git a/packages/kilo-ui/src/components/toast.css b/packages/kilo-ui/src/components/toast.css index f45c7565830..3645b3b95c9 100644 --- a/packages/kilo-ui/src/components/toast.css +++ b/packages/kilo-ui/src/components/toast.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Toast overrides – harmonized with @vscode/webview-ui-toolkit */ [data-component="toast"] { diff --git a/packages/kilo-ui/src/components/toast.tsx b/packages/kilo-ui/src/components/toast.tsx index 8f077174133..7e65ea33d9e 100644 --- a/packages/kilo-ui/src/components/toast.tsx +++ b/packages/kilo-ui/src/components/toast.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/toast" diff --git a/packages/kilo-ui/src/components/tooltip.css b/packages/kilo-ui/src/components/tooltip.css index 90fd285f469..f2c6f81a133 100644 --- a/packages/kilo-ui/src/components/tooltip.css +++ b/packages/kilo-ui/src/components/tooltip.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Kilo Tooltip overrides – sized to match @vscode/webview-ui-toolkit */ [data-component="tooltip"] { diff --git a/packages/kilo-ui/src/components/tooltip.tsx b/packages/kilo-ui/src/components/tooltip.tsx index 3c9dc669c1e..a1479303c2b 100644 --- a/packages/kilo-ui/src/components/tooltip.tsx +++ b/packages/kilo-ui/src/components/tooltip.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/tooltip" diff --git a/packages/kilo-ui/src/components/typewriter.tsx b/packages/kilo-ui/src/components/typewriter.tsx index 410fe1832b8..3e96e08f51b 100644 --- a/packages/kilo-ui/src/components/typewriter.tsx +++ b/packages/kilo-ui/src/components/typewriter.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/typewriter" diff --git a/packages/kilo-ui/src/context/code.tsx b/packages/kilo-ui/src/context/code.tsx index 98f1e351394..587f40b77a6 100644 --- a/packages/kilo-ui/src/context/code.tsx +++ b/packages/kilo-ui/src/context/code.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/code" diff --git a/packages/kilo-ui/src/context/data.tsx b/packages/kilo-ui/src/context/data.tsx index bf4843765d0..3f06c8ee64c 100644 --- a/packages/kilo-ui/src/context/data.tsx +++ b/packages/kilo-ui/src/context/data.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/data" diff --git a/packages/kilo-ui/src/context/dialog.tsx b/packages/kilo-ui/src/context/dialog.tsx index 18338bd44e5..7c2d2e23628 100644 --- a/packages/kilo-ui/src/context/dialog.tsx +++ b/packages/kilo-ui/src/context/dialog.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/dialog" diff --git a/packages/kilo-ui/src/context/diff.tsx b/packages/kilo-ui/src/context/diff.tsx index be53aa52cf6..41103ee61ff 100644 --- a/packages/kilo-ui/src/context/diff.tsx +++ b/packages/kilo-ui/src/context/diff.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/diff" diff --git a/packages/kilo-ui/src/context/helper.tsx b/packages/kilo-ui/src/context/helper.tsx index 84de698a098..d5b5c7450d6 100644 --- a/packages/kilo-ui/src/context/helper.tsx +++ b/packages/kilo-ui/src/context/helper.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/helper" diff --git a/packages/kilo-ui/src/context/i18n.tsx b/packages/kilo-ui/src/context/i18n.tsx index 4f655945a5f..63588e2affa 100644 --- a/packages/kilo-ui/src/context/i18n.tsx +++ b/packages/kilo-ui/src/context/i18n.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/i18n" diff --git a/packages/kilo-ui/src/context/index.ts b/packages/kilo-ui/src/context/index.ts index a2f821520d7..87374300894 100644 --- a/packages/kilo-ui/src/context/index.ts +++ b/packages/kilo-ui/src/context/index.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context" diff --git a/packages/kilo-ui/src/context/marked.tsx b/packages/kilo-ui/src/context/marked.tsx index e8adc0851ed..1ef709617c7 100644 --- a/packages/kilo-ui/src/context/marked.tsx +++ b/packages/kilo-ui/src/context/marked.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/marked" diff --git a/packages/kilo-ui/src/context/worker-pool.tsx b/packages/kilo-ui/src/context/worker-pool.tsx index babe6ea5a5b..263c05d9b4d 100644 --- a/packages/kilo-ui/src/context/worker-pool.tsx +++ b/packages/kilo-ui/src/context/worker-pool.tsx @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/context/worker-pool" diff --git a/packages/kilo-ui/src/hooks/index.ts b/packages/kilo-ui/src/hooks/index.ts index 8868ba7737c..c3b66ced39d 100644 --- a/packages/kilo-ui/src/hooks/index.ts +++ b/packages/kilo-ui/src/hooks/index.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/hooks" diff --git a/packages/kilo-ui/src/i18n/ar.ts b/packages/kilo-ui/src/i18n/ar.ts index 0e316b5369c..e0f874ac934 100644 --- a/packages/kilo-ui/src/i18n/ar.ts +++ b/packages/kilo-ui/src/i18n/ar.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/ar" diff --git a/packages/kilo-ui/src/i18n/br.ts b/packages/kilo-ui/src/i18n/br.ts index c44df1799aa..f3d4075c2fc 100644 --- a/packages/kilo-ui/src/i18n/br.ts +++ b/packages/kilo-ui/src/i18n/br.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/br" diff --git a/packages/kilo-ui/src/i18n/bs.ts b/packages/kilo-ui/src/i18n/bs.ts index a006a31d609..6e3a89546a2 100644 --- a/packages/kilo-ui/src/i18n/bs.ts +++ b/packages/kilo-ui/src/i18n/bs.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/bs" diff --git a/packages/kilo-ui/src/i18n/da.ts b/packages/kilo-ui/src/i18n/da.ts index ed2d8fdd367..42504eabefa 100644 --- a/packages/kilo-ui/src/i18n/da.ts +++ b/packages/kilo-ui/src/i18n/da.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/da" diff --git a/packages/kilo-ui/src/i18n/de.ts b/packages/kilo-ui/src/i18n/de.ts index d3bbfcae3f9..8e0b7feacce 100644 --- a/packages/kilo-ui/src/i18n/de.ts +++ b/packages/kilo-ui/src/i18n/de.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/de" diff --git a/packages/kilo-ui/src/i18n/en.ts b/packages/kilo-ui/src/i18n/en.ts index 62e59eb1ea7..ade8a9d7c05 100644 --- a/packages/kilo-ui/src/i18n/en.ts +++ b/packages/kilo-ui/src/i18n/en.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/en" diff --git a/packages/kilo-ui/src/i18n/es.ts b/packages/kilo-ui/src/i18n/es.ts index 97bb39cf0f6..20145b49382 100644 --- a/packages/kilo-ui/src/i18n/es.ts +++ b/packages/kilo-ui/src/i18n/es.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/es" diff --git a/packages/kilo-ui/src/i18n/fr.ts b/packages/kilo-ui/src/i18n/fr.ts index 4904a991439..1a1545020b4 100644 --- a/packages/kilo-ui/src/i18n/fr.ts +++ b/packages/kilo-ui/src/i18n/fr.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/fr" diff --git a/packages/kilo-ui/src/i18n/ja.ts b/packages/kilo-ui/src/i18n/ja.ts index 6cb87ad6c74..093bb1ff314 100644 --- a/packages/kilo-ui/src/i18n/ja.ts +++ b/packages/kilo-ui/src/i18n/ja.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/ja" diff --git a/packages/kilo-ui/src/i18n/ko.ts b/packages/kilo-ui/src/i18n/ko.ts index cc72b7202b1..872ef7b4ff0 100644 --- a/packages/kilo-ui/src/i18n/ko.ts +++ b/packages/kilo-ui/src/i18n/ko.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/ko" diff --git a/packages/kilo-ui/src/i18n/no.ts b/packages/kilo-ui/src/i18n/no.ts index 546d316f1a1..7f1ace59299 100644 --- a/packages/kilo-ui/src/i18n/no.ts +++ b/packages/kilo-ui/src/i18n/no.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/no" diff --git a/packages/kilo-ui/src/i18n/pl.ts b/packages/kilo-ui/src/i18n/pl.ts index 3b042cb4adc..9de3e796690 100644 --- a/packages/kilo-ui/src/i18n/pl.ts +++ b/packages/kilo-ui/src/i18n/pl.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/pl" diff --git a/packages/kilo-ui/src/i18n/ru.ts b/packages/kilo-ui/src/i18n/ru.ts index cd0f90ca5f9..2eb4a1d7421 100644 --- a/packages/kilo-ui/src/i18n/ru.ts +++ b/packages/kilo-ui/src/i18n/ru.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/ru" diff --git a/packages/kilo-ui/src/i18n/th.ts b/packages/kilo-ui/src/i18n/th.ts index e6e7e5b8bfb..78e4c8bc8d8 100644 --- a/packages/kilo-ui/src/i18n/th.ts +++ b/packages/kilo-ui/src/i18n/th.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/th" diff --git a/packages/kilo-ui/src/i18n/zh.ts b/packages/kilo-ui/src/i18n/zh.ts index e0e6e988680..5402471a979 100644 --- a/packages/kilo-ui/src/i18n/zh.ts +++ b/packages/kilo-ui/src/i18n/zh.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/zh" diff --git a/packages/kilo-ui/src/i18n/zht.ts b/packages/kilo-ui/src/i18n/zht.ts index 5a0328f9d7e..ba349b97d7e 100644 --- a/packages/kilo-ui/src/i18n/zht.ts +++ b/packages/kilo-ui/src/i18n/zht.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/i18n/zht" diff --git a/packages/kilo-ui/src/index.ts b/packages/kilo-ui/src/index.ts index 26c2b6a527d..3c6cc4b296c 100644 --- a/packages/kilo-ui/src/index.ts +++ b/packages/kilo-ui/src/index.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file // // @kilocode/kilo-ui // diff --git a/packages/kilo-ui/src/pierre/index.ts b/packages/kilo-ui/src/pierre/index.ts index 18f34e32023..ad2f1af9066 100644 --- a/packages/kilo-ui/src/pierre/index.ts +++ b/packages/kilo-ui/src/pierre/index.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/pierre" diff --git a/packages/kilo-ui/src/pierre/worker.ts b/packages/kilo-ui/src/pierre/worker.ts index 3c52cad72f1..31892568975 100644 --- a/packages/kilo-ui/src/pierre/worker.ts +++ b/packages/kilo-ui/src/pierre/worker.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/pierre/worker" diff --git a/packages/kilo-ui/src/styles/globals.css b/packages/kilo-ui/src/styles/globals.css index 15548a41e14..b995c31af2f 100644 --- a/packages/kilo-ui/src/styles/globals.css +++ b/packages/kilo-ui/src/styles/globals.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* * Kilo UI Global Overrides * diff --git a/packages/kilo-ui/src/styles/index.css b/packages/kilo-ui/src/styles/index.css index 575d6f05abe..70b0b2efb28 100644 --- a/packages/kilo-ui/src/styles/index.css +++ b/packages/kilo-ui/src/styles/index.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Wraps upstream styles and adds Kilo overrides */ @import "@opencode-ai/ui/styles"; diff --git a/packages/kilo-ui/src/styles/tailwind/index.css b/packages/kilo-ui/src/styles/tailwind/index.css index 5d62771ac66..c5e6aae4f02 100644 --- a/packages/kilo-ui/src/styles/tailwind/index.css +++ b/packages/kilo-ui/src/styles/tailwind/index.css @@ -1,4 +1,3 @@ -/* kilocode_change - new file */ /* Wraps upstream tailwind styles and adds Kilo overrides */ @import "@opencode-ai/ui/styles/tailwind"; diff --git a/packages/kilo-ui/src/theme/color.ts b/packages/kilo-ui/src/theme/color.ts index 7fda95ebe55..bd77d4fee4a 100644 --- a/packages/kilo-ui/src/theme/color.ts +++ b/packages/kilo-ui/src/theme/color.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/theme/color" diff --git a/packages/kilo-ui/src/theme/context.tsx b/packages/kilo-ui/src/theme/context.tsx index 79168f684cc..e54c99ead3b 100644 --- a/packages/kilo-ui/src/theme/context.tsx +++ b/packages/kilo-ui/src/theme/context.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file // Copy of @opencode-ai/ui/theme/context.tsx with two changes: // 1. Imports DEFAULT_THEMES from our local default-themes (which includes Kilo themes) // 2. Default theme changed from "oc-1" to "kilo" @@ -11,7 +10,7 @@ import { createSimpleContext } from "@opencode-ai/ui/context/helper" export type ColorScheme = "light" | "dark" | "system" -const DEFAULT_THEME_ID = "kilo" // kilocode_change: was "oc-1" +const DEFAULT_THEME_ID = "kilo" const STORAGE_KEYS = { THEME_ID: "opencode-theme-id", @@ -77,7 +76,7 @@ export const { use: useTheme, provider: ThemeProvider } = createSimpleContext({ init: (props: { defaultTheme?: string }) => { const [store, setStore] = createStore({ themes: DEFAULT_THEMES as Record, - themeId: props.defaultTheme ?? DEFAULT_THEME_ID, // kilocode_change: was "oc-1" + themeId: props.defaultTheme ?? DEFAULT_THEME_ID, colorScheme: "system" as ColorScheme, mode: getSystemMode(), previewThemeId: null as string | null, diff --git a/packages/kilo-ui/src/theme/default-themes.ts b/packages/kilo-ui/src/theme/default-themes.ts index 850777b4851..a048d4e5e4f 100644 --- a/packages/kilo-ui/src/theme/default-themes.ts +++ b/packages/kilo-ui/src/theme/default-themes.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import type { DesktopTheme } from "@opencode-ai/ui/theme/types" import { DEFAULT_THEMES as UPSTREAM_THEMES } from "@opencode-ai/ui/theme/default-themes" import kiloJson from "./themes/kilo.json" diff --git a/packages/kilo-ui/src/theme/index.ts b/packages/kilo-ui/src/theme/index.ts index 23759871b77..995377cbe96 100644 --- a/packages/kilo-ui/src/theme/index.ts +++ b/packages/kilo-ui/src/theme/index.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file export type { DesktopTheme, ThemeSeedColors, diff --git a/packages/kilo-ui/src/theme/loader.ts b/packages/kilo-ui/src/theme/loader.ts index 6c9a4ab5683..6de61d80688 100644 --- a/packages/kilo-ui/src/theme/loader.ts +++ b/packages/kilo-ui/src/theme/loader.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/theme/loader" diff --git a/packages/kilo-ui/src/theme/resolve.ts b/packages/kilo-ui/src/theme/resolve.ts index 67036d92290..752e0dbaf66 100644 --- a/packages/kilo-ui/src/theme/resolve.ts +++ b/packages/kilo-ui/src/theme/resolve.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/theme/resolve" diff --git a/packages/kilo-ui/src/theme/types.ts b/packages/kilo-ui/src/theme/types.ts index 0f38e4b5cfe..d8620363576 100644 --- a/packages/kilo-ui/src/theme/types.ts +++ b/packages/kilo-ui/src/theme/types.ts @@ -1,2 +1 @@ -// kilocode_change - new file export * from "@opencode-ai/ui/theme/types" diff --git a/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/default-chromium-linux.png b/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/default-chromium-linux.png index f8d8fc65ab0..3ec89b92089 100644 --- a/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/default-chromium-linux.png +++ b/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/default-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c67c7cc21cd458c632228bdcee310615fae82c6d4c76e4d1170fa00224a9ac3 -size 29215 +oid sha256:1de30d219cd299acf26c9fe473c00f18cf057297db2e9b1ae44fb3116b0392f0 +size 31305 diff --git a/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/with-steps-expanded-chromium-linux.png b/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/with-steps-expanded-chromium-linux.png index f8d8fc65ab0..3ec89b92089 100644 --- a/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/with-steps-expanded-chromium-linux.png +++ b/packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/components-sessionturn/with-steps-expanded-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6c67c7cc21cd458c632228bdcee310615fae82c6d4c76e4d1170fa00224a9ac3 -size 29215 +oid sha256:1de30d219cd299acf26c9fe473c00f18cf057297db2e9b1ae44fb3116b0392f0 +size 31305 diff --git a/packages/kilo-vscode/.gitignore b/packages/kilo-vscode/.gitignore index 07a0b88ee57..99ae09f5426 100644 --- a/packages/kilo-vscode/.gitignore +++ b/packages/kilo-vscode/.gitignore @@ -1,3 +1,5 @@ bin/ out/ -.vscode-test/ \ No newline at end of file +.vscode-test/ +storybook-static/ +test-results/ \ No newline at end of file diff --git a/packages/kilo-vscode/.storybook/main.ts b/packages/kilo-vscode/.storybook/main.ts new file mode 100644 index 00000000000..98be6d87566 --- /dev/null +++ b/packages/kilo-vscode/.storybook/main.ts @@ -0,0 +1,27 @@ +import type { StorybookConfig } from "storybook-solidjs-vite" +import { mergeConfig } from "vite" +import solidPlugin from "vite-plugin-solid" + +const config: StorybookConfig = { + framework: "storybook-solidjs-vite", + stories: ["../webview-ui/src/stories/**/*.stories.@(ts|tsx)"], + addons: ["@storybook/addon-docs"], + refs: {}, + viteFinal: async (config) => { + return mergeConfig(config, { + plugins: [solidPlugin()], + resolve: { + conditions: ["browser", "solid", "module", "import"], + }, + esbuild: { + jsxImportSource: "solid-js", + jsx: "automatic", + }, + worker: { + format: "es", + }, + }) + }, +} + +export default config diff --git a/packages/kilo-vscode/.storybook/preview.tsx b/packages/kilo-vscode/.storybook/preview.tsx new file mode 100644 index 00000000000..f69d799def4 --- /dev/null +++ b/packages/kilo-vscode/.storybook/preview.tsx @@ -0,0 +1,84 @@ +/** @jsxImportSource solid-js */ +import type { Preview, SolidRenderer } from "storybook-solidjs-vite" +import type { DecoratorFunction } from "storybook/internal/types" +// Reference kilo-ui stories helpers directly — not exported via package.json +import { applyKiloTheme, applyVscodeTheme, clearVscodeTheme } from "../../kilo-ui/src/stories/theme-decorator" +import "../../kilo-ui/.storybook/fonts.css" +import "@kilocode/kilo-ui/styles" +import "../webview-ui/src/styles/chat.css" + +const themeDecorator: DecoratorFunction = (Story, context) => { + const themeId = (context.globals["theme"] as string) ?? "kilo-vscode" + const vscodeThemeId = (context.globals["vscodeTheme"] as string) ?? "dark-modern" + + const colorScheme = (() => { + if (themeId === "kilo-vscode") return applyVscodeTheme(vscodeThemeId) + clearVscodeTheme() + return (context.globals["colorScheme"] as "light" | "dark") ?? "dark" + })() + + applyKiloTheme(themeId, colorScheme) + document.body.style.background = "var(--background-base)" + document.body.style.color = "var(--text-base)" + return Story() +} + +const preview: Preview = { + parameters: { + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/i, + }, + }, + layout: "fullscreen", + }, + decorators: [themeDecorator], + globalTypes: { + theme: { + description: "Theme", + toolbar: { + title: "Theme", + icon: "paintbrush", + items: [ + { value: "kilo-vscode", title: "Kilo VSCode" }, + { value: "kilo", title: "Kilo" }, + ], + dynamicTitle: true, + }, + }, + colorScheme: { + description: "Color Scheme", + toolbar: { + title: "Color Scheme", + icon: "circlehollow", + items: [ + { value: "dark", title: "Dark", icon: "moon" }, + { value: "light", title: "Light", icon: "sun" }, + ], + dynamicTitle: true, + }, + }, + vscodeTheme: { + description: "VSCode Theme", + toolbar: { + title: "VSCode Theme", + icon: "browser", + items: [ + { value: "dark-modern", title: "Dark Modern (default)" }, + { value: "dark-plus", title: "Dark+" }, + { value: "light-modern", title: "Light Modern" }, + { value: "hc-black", title: "High Contrast" }, + ], + dynamicTitle: true, + }, + }, + }, + initialGlobals: { + theme: "kilo-vscode", + colorScheme: "dark", + vscodeTheme: "dark-modern", + }, +} + +export default preview diff --git a/packages/kilo-vscode/.storybook/tsconfig.json b/packages/kilo-vscode/.storybook/tsconfig.json new file mode 100644 index 00000000000..4c9af3a4816 --- /dev/null +++ b/packages/kilo-vscode/.storybook/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../webview-ui/tsconfig.json", + "compilerOptions": { + "jsx": "preserve", + "jsxImportSource": "solid-js" + }, + "include": ["./**/*", "../webview-ui/src/**/*"] +} diff --git a/packages/kilo-vscode/package.json b/packages/kilo-vscode/package.json index ea93e0ad636..b71dbe4501b 100644 --- a/packages/kilo-vscode/package.json +++ b/packages/kilo-vscode/package.json @@ -2,7 +2,7 @@ "name": "kilo-code", "displayName": "Kilo Code: AI Coding Agent, Copilot, and Autocomplete", "description": "Open Source AI coding agent that generates code from natural language, automates tasks, and runs terminal commands. Features inline autocomplete, browser automation, automated refactoring, and custom modes for planning, coding, and debugging. Supports 500+ AI models including Claude (Anthropic), Gemini, Grok, GPT, Codex and GLM.", - "version": "7.0.36", + "version": "7.0.37", "icon": "assets/icons/logo-outline-black.png", "galleryBanner": { "color": "#FFFFFF", @@ -110,6 +110,11 @@ "dark": "assets/icons/kilo-dark.svg" } }, + { + "command": "kilo-code.new.openMigrationWizard", + "title": "Migrate Settings from Legacy Version", + "category": "Kilo Code" + }, { "command": "kilo-code.new.autocomplete.generateSuggestions", "title": "Generate Suggested Edits", @@ -672,9 +677,15 @@ "lint": "eslint src", "test": "vscode-test", "test:unit": "bun test tests/unit/", - "rebuild-sdk": "bun run --cwd ../sdk/js build" + "rebuild-sdk": "bun run --cwd ../sdk/js build", + "storybook": "storybook dev -p 6007", + "build-storybook": "storybook build -o storybook-static", + "test:visual": "playwright test", + "test:visual:update": "playwright test --update-snapshots" }, "devDependencies": { + "@playwright/test": "1.58.2", + "@storybook/addon-docs": "10.2.10", "@types/diff": "^6.0.0", "@types/mocha": "^10.0.10", "@types/node": "22.x", @@ -688,9 +699,13 @@ "eslint-config-prettier": "^10.1.8", "prettier": "^3.8.1", "qrcode": "^1.5.4", + "storybook": "10.2.10", + "storybook-solidjs-vite": "10.0.9", "ts-morph": "27.0.2", "typescript": "^5.9.3", "typescript-eslint": "^8.54.0", + "vite": "7.3.1", + "vite-plugin-solid": "2.11.10", "@vscode/vsce": "^3.7.1" }, "dependencies": { diff --git a/packages/kilo-vscode/playwright.config.ts b/packages/kilo-vscode/playwright.config.ts new file mode 100644 index 00000000000..30680574fc8 --- /dev/null +++ b/packages/kilo-vscode/playwright.config.ts @@ -0,0 +1,40 @@ +import { defineConfig, devices } from "@playwright/test" + +export default defineConfig({ + testDir: "./tests", + testMatch: "**/*.spec.ts", + fullyParallel: true, + forbidOnly: !!process.env["CI"], + retries: process.env["CI"] ? 1 : 0, + workers: process.env["PLAYWRIGHT_WORKERS"] + ? Number.parseInt(process.env["PLAYWRIGHT_WORKERS"]!, 10) || undefined + : undefined, + reporter: [["html", { open: "never" }], ["list"]], + use: { + baseURL: "http://localhost:6007", + // VS Code sidebar is typically 350-450px wide + viewport: { width: 420, height: 720 }, + reducedMotion: "reduce", + screenshot: "only-on-failure", + }, + projects: [ + { + name: "chromium", + use: { ...devices["Desktop Chrome"], viewport: { width: 420, height: 720 } }, + }, + ], + webServer: { + command: + "bunx storybook build -o ./storybook-static && bunx http-server ./storybook-static -p 6007 --silent", + url: "http://localhost:6007", + reuseExistingServer: !process.env["CI"], + timeout: 300_000, + }, + timeout: 60_000, + expect: { + timeout: 10_000, + toHaveScreenshot: { + maxDiffPixelRatio: 0.01, + }, + }, +}) diff --git a/packages/kilo-vscode/src/KiloProvider.ts b/packages/kilo-vscode/src/KiloProvider.ts index 6e3d261639f..2a911b0f26a 100644 --- a/packages/kilo-vscode/src/KiloProvider.ts +++ b/packages/kilo-vscode/src/KiloProvider.ts @@ -17,6 +17,9 @@ import { handleChatCompletionRequest } from "./services/autocomplete/chat-autoco import { handleChatCompletionAccepted } from "./services/autocomplete/chat-autocomplete/handleChatCompletionAccepted" import { buildWebviewHtml } from "./utils" import { TelemetryProxy, type TelemetryPropertiesProvider } from "./services/telemetry" +// legacy-migration start +import * as MigrationService from "./legacy-migration/migration-service" +// legacy-migration end import { sessionToWebview, indexProvidersById, @@ -62,6 +65,10 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper private pendingSessionRefresh = false private unsubscribeEvent: (() => void) | null = null private unsubscribeState: (() => void) | null = null + /** Cached legacy migration data so migrate() doesn't re-read from disk/SecretStorage. */ // legacy-migration + private cachedLegacyData: import("./legacy-migration/legacy-types").LegacyMigrationData | null = null // legacy-migration + /** Guard to prevent checkAndShowMigrationWizard running concurrently. */ // legacy-migration + private migrationCheckInFlight = false // legacy-migration private unsubscribeNotificationDismiss: (() => void) | null = null private webviewMessageDisposable: vscode.Disposable | null = null @@ -157,6 +164,16 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper data: profileData, }) } + + // legacy-migration start + // Only show the migration wizard once the CLI connection is established so the + // webview has finished loading providers/agents before we navigate to the wizard. + if (reason === "webviewReady" && this.connectionState === "connected") { + void this.checkAndShowMigrationWizard() + } else if (reason === "sse-connected") { + void this.checkAndShowMigrationWizard() + } + // legacy-migration end } public resolveWebviewView( @@ -540,6 +557,20 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper this.postMessage({ type: "variantsLoaded", variants }) break } + // legacy-migration start + case "requestLegacyMigrationData": + void this.handleRequestLegacyMigrationData() + break + case "startLegacyMigration": + void this.handleStartLegacyMigration(message.selections) + break + case "skipLegacyMigration": + void this.handleSkipLegacyMigration() + break + case "clearLegacyData": + void this.handleClearLegacyData() + break + // legacy-migration end case "enhancePrompt": { const sdkClient = this.client if (!sdkClient) { @@ -1736,7 +1767,6 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper * settings from the previous version of the extension which shares the same * extension ID and "kilo-code.*" namespace. */ - // kilocode_change start private async handleResetAllSettings(): Promise { const confirmed = await vscode.window.showWarningMessage( "Reset all Kilo Code extension settings to defaults?", @@ -1764,7 +1794,6 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper this.sendBrowserSettings() this.sendNotificationSettings() } - // kilocode_change end /** * Read the current browser automation settings and push them to the webview. @@ -1812,6 +1841,13 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper return } + // Refresh provider and agent lists when the server signals a state disposal + if (event.type === "server.instance.disposed" || event.type === "global.disposed") { + void this.fetchAndSendProviders() + void this.fetchAndSendAgents() + return + } + // Forward relevant events to webview // Side effects that must happen before the webview message is sent if (event.type === "session.created" && !this.currentSession) { @@ -1991,6 +2027,113 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper }) } + // legacy-migration start ------------------------------------------------------- + + /** + * Checks for legacy data on first run and auto-navigates to the migration wizard + * if the user has not yet been prompted. + */ + private async checkAndShowMigrationWizard(): Promise { + if (!this.extensionContext) return + if (this.migrationCheckInFlight) return + const status = MigrationService.getMigrationStatus(this.extensionContext) + if (status) return // already prompted (skipped or completed) + + this.migrationCheckInFlight = true + const data = await MigrationService.detectLegacyData(this.extensionContext) + this.migrationCheckInFlight = false + + if (!data.hasData) return + + // Cache so migrate() doesn't re-read from SecretStorage/disk + this.cachedLegacyData = data + + console.log("[Kilo New] KiloProvider: 🔄 Legacy data detected, showing migration wizard") + this.postMessage({ type: "navigate", view: "migration" }) + this.postMessage({ + type: "legacyMigrationData", + data: { + providers: data.providers, + mcpServers: data.mcpServers, + customModes: data.customModes, + defaultModel: data.defaultModel, + settings: data.settings, + }, + }) + } + + /** Sends the detected legacy data to the webview on explicit request. */ + private async handleRequestLegacyMigrationData(): Promise { + if (!this.extensionContext) return + const data = await MigrationService.detectLegacyData(this.extensionContext) + // Cache so migrate() doesn't re-read from SecretStorage/disk + this.cachedLegacyData = data + this.postMessage({ + type: "legacyMigrationData", + data: { + providers: data.providers, + mcpServers: data.mcpServers, + customModes: data.customModes, + defaultModel: data.defaultModel, + settings: data.settings, + }, + }) + } + + /** Runs the migration for the selected items. */ + private async handleStartLegacyMigration( + selections: import("./legacy-migration/legacy-types").MigrationSelections, + ): Promise { + if (!this.extensionContext || !this.client) return + try { + const results = await MigrationService.migrate( + this.extensionContext, + this.client, + selections, + (item, status, message) => { + this.postMessage({ type: "legacyMigrationProgress", item, status, message }) + }, + this.cachedLegacyData?.settings, + ) + // Only mark as completed if at least one item succeeded — if everything failed + // the user can still re-run migration via Settings → About. + const anySuccess = results.some((r) => r.status === "success") + if (anySuccess) { + await MigrationService.setMigrationStatus(this.extensionContext, "completed") + } + // Refresh providers so webview immediately sees the newly-migrated API keys + await this.fetchAndSendProviders() + this.postMessage({ type: "legacyMigrationComplete", results }) + } catch (error) { + console.error("[Kilo New] KiloProvider: ❌ Migration failed", error) + this.postMessage({ + type: "legacyMigrationComplete", + results: [ + { + item: "Migration", + category: "settings", + status: "error", + message: error instanceof Error ? error.message : String(error), + }, + ], + }) + } + } + + /** Records that the user skipped migration. */ + private async handleSkipLegacyMigration(): Promise { + if (!this.extensionContext) return + await MigrationService.setMigrationStatus(this.extensionContext, "skipped") + } + + /** Clears legacy data from SecretStorage and globalState after user opts in. */ + private async handleClearLegacyData(): Promise { + if (!this.extensionContext) return + await MigrationService.clearLegacyData(this.extensionContext) + } + + // legacy-migration end --------------------------------------------------------- + /** * Dispose of the provider and clean up subscriptions. * Does NOT kill the server — that's the connection service's job. diff --git a/packages/kilo-vscode/src/extension.ts b/packages/kilo-vscode/src/extension.ts index ecd6e1069b9..e95d625f083 100644 --- a/packages/kilo-vscode/src/extension.ts +++ b/packages/kilo-vscode/src/extension.ts @@ -70,6 +70,11 @@ export function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand("kilo-code.new.settingsButtonClicked", () => { provider.postMessage({ type: "action", action: "settingsButtonClicked" }) }), + // legacy-migration start + vscode.commands.registerCommand("kilo-code.new.openMigrationWizard", () => { + provider.postMessage({ type: "navigate", view: "migration" }) + }), + // legacy-migration end vscode.commands.registerCommand("kilo-code.new.openInTab", () => { return openKiloInNewTab(context, connectionService) }), diff --git a/packages/kilo-vscode/src/legacy-migration/index.ts b/packages/kilo-vscode/src/legacy-migration/index.ts new file mode 100644 index 00000000000..03927ac174a --- /dev/null +++ b/packages/kilo-vscode/src/legacy-migration/index.ts @@ -0,0 +1,8 @@ +/** + * legacy-migration - Barrel export. + * Delete this entire directory when dropping legacy migration support. + */ +export * from "./legacy-types" +export * from "./provider-mapping" +export * from "./migration-messages" +export * from "./migration-service" diff --git a/packages/kilo-vscode/src/legacy-migration/legacy-types.ts b/packages/kilo-vscode/src/legacy-migration/legacy-types.ts new file mode 100644 index 00000000000..37e95f1925b --- /dev/null +++ b/packages/kilo-vscode/src/legacy-migration/legacy-types.ts @@ -0,0 +1,312 @@ +/** + * legacy-migration - Types for legacy Kilo Code extension (v5.x) data structures. + * + * These types represent the shapes stored in VS Code SecretStorage and on disk + * by the legacy extension (kilocode.kilo-code v5.x, a Roo Code fork). + * They are intentionally loose (allowing [key: string]: unknown) to tolerate + * schema drift between legacy versions. + */ + +// --------------------------------------------------------------------------- +// Provider profiles (stored in SecretStorage under "roo_cline_config_api_config") +// --------------------------------------------------------------------------- + +export interface LegacyProviderProfiles { + currentApiConfigName: string + apiConfigs: Record + modeApiConfigs?: Record +} + +/** + * Flat union of every provider-specific field from the legacy extension. + * Only the fields we actually need for migration are explicitly typed; + * the rest are captured by the index signature. + */ +export interface LegacyProviderSettings { + id?: string + apiProvider?: string + apiModelId?: string + + // Anthropic + apiKey?: string + anthropicBaseUrl?: string + + // OpenRouter + openRouterApiKey?: string + openRouterModelId?: string + openRouterBaseUrl?: string + + // OpenAI (custom/compatible) + openAiApiKey?: string + openAiModelId?: string + openAiBaseUrl?: string + + // OpenAI Native + openAiNativeApiKey?: string + openAiNativeBaseUrl?: string + + // Gemini + geminiApiKey?: string + googleGeminiBaseUrl?: string + + // Vertex AI + vertexJsonCredentials?: string + vertexProjectId?: string + vertexRegion?: string + + // AWS Bedrock + awsAccessKey?: string + awsSecretKey?: string + awsSessionToken?: string + awsRegion?: string + awsApiKey?: string + + // DeepSeek + deepSeekApiKey?: string + deepSeekBaseUrl?: string + + // Mistral + mistralApiKey?: string + + // Groq + groqApiKey?: string + + // xAI + xaiApiKey?: string + + // Fireworks + fireworksApiKey?: string + + // Featherless + featherlessApiKey?: string + + // Cerebras + cerebrasApiKey?: string + + // SambaNova + sambaNovaApiKey?: string + + // Ollama + ollamaApiKey?: string + ollamaBaseUrl?: string + ollamaModelId?: string + + // LM Studio + lmStudioBaseUrl?: string + lmStudioModelId?: string + + // Kilocode + kilocodeToken?: string + kilocodeModel?: string + kilocodeOrganizationId?: string + + // LiteLLM + litellmApiKey?: string + litellmBaseUrl?: string + litellmModelId?: string + + // DeepInfra + deepInfraApiKey?: string + deepInfraBaseUrl?: string + deepInfraModelId?: string + + // Chutes + chutesApiKey?: string + + // Baseten + basetenApiKey?: string + + // Corethink + corethinkApiKey?: string + + // Unbound + unboundApiKey?: string + unboundModelId?: string + + // Requesty + requestyApiKey?: string + requestyBaseUrl?: string + requestyModelId?: string + + // Hugging Face + huggingFaceApiKey?: string + huggingFaceModelId?: string + + // IO Intelligence + ioIntelligenceApiKey?: string + ioIntelligenceModelId?: string + + // Vercel AI Gateway + vercelAiGatewayApiKey?: string + vercelAiGatewayModelId?: string + + // Z.ai + zaiApiKey?: string + + // Moonshot + moonshotApiKey?: string + moonshotBaseUrl?: string + + // Doubao + doubaoApiKey?: string + doubaoBaseUrl?: string + + // MiniMax + minimaxApiKey?: string + minimaxBaseUrl?: string + + // OVHcloud + ovhCloudAiEndpointsApiKey?: string + ovhCloudAiEndpointsBaseUrl?: string + ovhCloudAiEndpointsModelId?: string + + // Inception Labs + inceptionLabsApiKey?: string + inceptionLabsBaseUrl?: string + inceptionLabsModelId?: string + + // SAP AI Core + sapAiCoreServiceKey?: string + + // Synthetic + syntheticApiKey?: string + + // Allow dynamic property access for provider-mapping lookups + [key: string]: unknown +} + +// --------------------------------------------------------------------------- +// MCP settings (stored on disk at /settings/mcp_settings.json) +// --------------------------------------------------------------------------- + +export interface LegacyMcpSettings { + mcpServers: Record +} + +export interface LegacyMcpServer { + type?: "stdio" | "sse" | "streamable-http" + command?: string + args?: string[] + cwd?: string + url?: string + env?: Record + headers?: Record + disabled?: boolean + timeout?: number +} + +// --------------------------------------------------------------------------- +// Autocomplete settings (stored in globalState under "ghostServiceSettings") +// --------------------------------------------------------------------------- + +export interface LegacyAutocompleteSettings { + enableAutoTrigger?: boolean + enableSmartInlineTaskKeybinding?: boolean + enableChatAutocomplete?: boolean +} + +// --------------------------------------------------------------------------- +// Settings (stored in VS Code globalState under "kilo-code.*" keys) +// --------------------------------------------------------------------------- + +export interface LegacySettings { + autoApprovalEnabled?: boolean + allowedCommands?: string[] + deniedCommands?: string[] + // Fine-grained auto-approval (legacy globalState keys — no prefix) + alwaysAllowReadOnly?: boolean + alwaysAllowReadOnlyOutsideWorkspace?: boolean + alwaysAllowWrite?: boolean + alwaysAllowExecute?: boolean + alwaysAllowMcp?: boolean + alwaysAllowModeSwitch?: boolean + alwaysAllowSubtasks?: boolean + language?: string + autocomplete?: LegacyAutocompleteSettings +} + +// --------------------------------------------------------------------------- +// Custom modes (stored on disk at /settings/custom_modes.yaml) +// --------------------------------------------------------------------------- + +export interface LegacyCustomModesFile { + customModes: LegacyCustomMode[] +} + +export interface LegacyCustomMode { + slug: string + name: string + roleDefinition: string + customInstructions?: string + whenToUse?: string + description?: string + groups: Array]> +} + +// --------------------------------------------------------------------------- +// Migration data shapes +// --------------------------------------------------------------------------- + +export interface MigrationProviderInfo { + profileName: string + provider: string + model?: string + hasApiKey: boolean + supported: boolean + newProviderName?: string +} + +export interface MigrationMcpServerInfo { + name: string + type: string +} + +export interface MigrationCustomModeInfo { + name: string + slug: string +} + +export interface LegacyMigrationData { + providers: MigrationProviderInfo[] + mcpServers: MigrationMcpServerInfo[] + customModes: MigrationCustomModeInfo[] + defaultModel?: { provider: string; model: string } + settings?: LegacySettings + hasData: boolean +} + +export interface MigrationAutoApprovalSelections { + /** Master toggle + command allowlist/denylist */ + commandRules: boolean + /** Read permission (alwaysAllowReadOnly / alwaysAllowReadOnlyOutsideWorkspace) */ + readPermission: boolean + /** Write permission (alwaysAllowWrite) */ + writePermission: boolean + /** Execute permission (alwaysAllowExecute) */ + executePermission: boolean + /** MCP tool permission (alwaysAllowMcp) */ + mcpPermission: boolean + /** Task/subtask permission (alwaysAllowModeSwitch / alwaysAllowSubtasks) */ + taskPermission: boolean +} + +export interface MigrationSettingsSelections { + autoApproval: MigrationAutoApprovalSelections + language: boolean + autocomplete: boolean +} + +export interface MigrationSelections { + providers: string[] + mcpServers: string[] + customModes: string[] + defaultModel: boolean + settings: MigrationSettingsSelections +} + +export interface MigrationResultItem { + item: string + category: "provider" | "mcpServer" | "customMode" | "defaultModel" | "settings" + status: "success" | "warning" | "error" + message?: string +} diff --git a/packages/kilo-vscode/src/legacy-migration/migration-messages.ts b/packages/kilo-vscode/src/legacy-migration/migration-messages.ts new file mode 100644 index 00000000000..59063880510 --- /dev/null +++ b/packages/kilo-vscode/src/legacy-migration/migration-messages.ts @@ -0,0 +1,71 @@ +/** + * legacy-migration - Message type definitions for migration wizard communication. + * + * These types extend the extension ↔ webview message contract specifically for + * the legacy migration wizard. They are defined here to keep them isolated from + * the main messages.ts file and easy to remove. + */ + +import type { + MigrationProviderInfo, + MigrationMcpServerInfo, + MigrationCustomModeInfo, + MigrationSelections, + MigrationResultItem, + LegacySettings, +} from "./legacy-types" + +// --------------------------------------------------------------------------- +// Extension → Webview +// --------------------------------------------------------------------------- + +/** Sends detected legacy data to the wizard for display in the selection step. */ +export interface LegacyMigrationDataMessage { + type: "legacyMigrationData" + data: { + providers: MigrationProviderInfo[] + mcpServers: MigrationMcpServerInfo[] + customModes: MigrationCustomModeInfo[] + defaultModel?: { provider: string; model: string } + settings?: LegacySettings + } +} + +/** Real-time progress update for a single item being migrated. */ +export interface LegacyMigrationProgressMessage { + type: "legacyMigrationProgress" + item: string + status: "migrating" | "success" | "warning" | "error" + message?: string +} + +/** Final results once all selected items have been processed. */ +export interface LegacyMigrationCompleteMessage { + type: "legacyMigrationComplete" + results: MigrationResultItem[] +} + +// --------------------------------------------------------------------------- +// Webview → Extension +// --------------------------------------------------------------------------- + +/** Webview requests the legacy data payload (e.g. on component mount). */ +export interface RequestLegacyMigrationDataMessage { + type: "requestLegacyMigrationData" +} + +/** User has confirmed selections and wants to start migration. */ +export interface StartLegacyMigrationMessage { + type: "startLegacyMigration" + selections: MigrationSelections +} + +/** User chose to skip migration entirely. */ +export interface SkipLegacyMigrationMessage { + type: "skipLegacyMigration" +} + +/** User opted to clear legacy data after successful migration. */ +export interface ClearLegacyDataMessage { + type: "clearLegacyData" +} diff --git a/packages/kilo-vscode/src/legacy-migration/migration-service.ts b/packages/kilo-vscode/src/legacy-migration/migration-service.ts new file mode 100644 index 00000000000..6ab8f576b49 --- /dev/null +++ b/packages/kilo-vscode/src/legacy-migration/migration-service.ts @@ -0,0 +1,970 @@ +/** + * legacy-migration - Core migration service. + * + * Reads legacy Kilo Code v5.x data from VS Code SecretStorage and the extension's + * global storage directory, then writes it to the new CLI backend via the SDK. + */ + +import * as vscode from "vscode" +import type { KiloClient } from "@kilocode/sdk/v2/client" +import type { + McpLocalConfig, + McpRemoteConfig, + AgentConfig, + PermissionConfig, + PermissionObjectConfig, +} from "@kilocode/sdk/v2/client" +import { PROVIDER_MAP, UNSUPPORTED_PROVIDERS, DEFAULT_MODE_SLUGS } from "./provider-mapping" +import type { + LegacyProviderProfiles, + LegacyProviderSettings, + LegacyMcpSettings, + LegacyCustomMode, + LegacyMcpServer, + LegacySettings, + LegacyAutocompleteSettings, + LegacyMigrationData, + MigrationSelections, + MigrationAutoApprovalSelections, + MigrationProviderInfo, + MigrationMcpServerInfo, + MigrationCustomModeInfo, + MigrationResultItem, +} from "./legacy-types" + +// --------------------------------------------------------------------------- +// Constants +// --------------------------------------------------------------------------- + +const SECRET_KEY = "roo_cline_config_api_config" +const MIGRATION_STATUS_KEY = "kilo.legacyMigrationStatus" + +type MigrationStatus = "completed" | "skipped" + +// --------------------------------------------------------------------------- +// Status helpers +// --------------------------------------------------------------------------- + +export function getMigrationStatus(context: vscode.ExtensionContext): MigrationStatus | undefined { + return context.globalState.get(MIGRATION_STATUS_KEY) +} + +export async function setMigrationStatus(context: vscode.ExtensionContext, status: MigrationStatus): Promise { + await context.globalState.update(MIGRATION_STATUS_KEY, status) +} + +// --------------------------------------------------------------------------- +// Detection +// --------------------------------------------------------------------------- + +/** + * Reads legacy data from SecretStorage and global storage files. + * Returns a structured summary for display in the migration wizard. + */ +export async function detectLegacyData(context: vscode.ExtensionContext): Promise { + const profiles = await readLegacyProviderProfiles(context) + const mcpSettings = await readLegacyMcpSettings(context) + const customModes = await readLegacyCustomModes(context) + const settings = readLegacySettings(context) + + const providers = buildProviderList(profiles) + const mcpServers = buildMcpServerList(mcpSettings) + const modes = buildCustomModeList(customModes) + const defaultModel = resolveDefaultModel(profiles) + + const hasSettings = + settings.autoApprovalEnabled !== undefined || + (settings.allowedCommands?.length ?? 0) > 0 || + (settings.deniedCommands?.length ?? 0) > 0 || + settings.alwaysAllowReadOnly !== undefined || + settings.alwaysAllowReadOnlyOutsideWorkspace !== undefined || + settings.alwaysAllowWrite !== undefined || + settings.alwaysAllowExecute !== undefined || + settings.alwaysAllowMcp !== undefined || + settings.alwaysAllowModeSwitch !== undefined || + settings.alwaysAllowSubtasks !== undefined || + Boolean(settings.language) || + Boolean(settings.autocomplete) + + const hasData = providers.length > 0 || mcpServers.length > 0 || modes.length > 0 || hasSettings + + return { + providers, + mcpServers, + customModes: modes, + defaultModel, + settings: hasSettings ? settings : undefined, + hasData, + } +} + +// --------------------------------------------------------------------------- +// Migration +// --------------------------------------------------------------------------- + +export type ProgressCallback = ( + item: string, + status: "migrating" | "success" | "warning" | "error", + message?: string, +) => void + +/** + * Executes migration for the selected items. + * Calls onProgress for each item with real-time status updates. + * Pass `cachedSettings` (from a prior detectLegacyData call) to avoid re-reading + * globalState. Provider profiles, MCP servers, and custom modes are always re-read + * from SecretStorage/disk to ensure the data is current at migration time. + */ +export async function migrate( + context: vscode.ExtensionContext, + client: KiloClient, + selections: MigrationSelections, + onProgress: ProgressCallback, + cachedSettings?: LegacySettings, +): Promise { + const profiles = await readLegacyProviderProfiles(context) + const mcpSettings = await readLegacyMcpSettings(context) + const customModes = await readLegacyCustomModes(context) + const legacySettings = cachedSettings ?? readLegacySettings(context) + + const results: MigrationResultItem[] = [] + + // Migrate provider API keys + for (const profileName of selections.providers) { + const settings = profiles?.apiConfigs[profileName] + if (!settings) { + results.push({ item: profileName, category: "provider", status: "error", message: "Profile not found" }) + continue + } + onProgress(profileName, "migrating") + const result = await migrateProvider(profileName, settings, client) + results.push(result) + onProgress(profileName, result.status, result.message) + } + + // Migrate MCP servers + if (selections.mcpServers.length > 0 && mcpSettings) { + const mcpConfig: Record = {} + for (const name of selections.mcpServers) { + const server = mcpSettings.mcpServers[name] + if (!server) { + results.push({ item: name, category: "mcpServer", status: "error", message: "Server not found" }) + continue + } + onProgress(name, "migrating") + const converted = convertMcpServer(server) + if (converted) { + mcpConfig[name] = converted + results.push({ item: name, category: "mcpServer", status: "success" }) + onProgress(name, "success") + } else { + results.push({ + item: name, + category: "mcpServer", + status: "warning", + message: "Could not convert server config", + }) + onProgress(name, "warning", "Could not convert server config") + } + } + if (Object.keys(mcpConfig).length > 0) { + await client.global.config.update({ config: { mcp: mcpConfig } }) + } + } + + // Migrate custom modes as agents + if (selections.customModes.length > 0 && customModes) { + const agentConfig: Record = {} + for (const slug of selections.customModes) { + const mode = customModes.find((m) => m.slug === slug) + if (!mode) { + results.push({ item: slug, category: "customMode", status: "error", message: "Mode not found" }) + continue + } + onProgress(mode.name, "migrating") + agentConfig[slug] = convertCustomMode(mode) + results.push({ item: mode.name, category: "customMode", status: "success" }) + onProgress(mode.name, "success") + } + if (Object.keys(agentConfig).length > 0) { + await client.global.config.update({ config: { agent: agentConfig } }) + } + } + + // Migrate default model + if (selections.defaultModel && profiles) { + const activeName = profiles.currentApiConfigName + const active = profiles.apiConfigs[activeName] + if (active) { + onProgress("Default model", "migrating") + const result = await migrateDefaultModel(active, client) + results.push(result) + onProgress("Default model", result.status, result.message) + } + } + + // Migrate auto-approval settings (granular, each selected item is independent) + const apSel = selections.settings.autoApproval + if ( + apSel.commandRules || + apSel.readPermission || + apSel.writePermission || + apSel.executePermission || + apSel.mcpPermission || + apSel.taskPermission + ) { + const apItems = await migrateAutoApproval(legacySettings, apSel, client, onProgress) + results.push(...apItems) + } + + // Migrate language setting + if (selections.settings.language && legacySettings.language) { + onProgress("Language preference", "migrating") + const result = await migrateLanguage(legacySettings.language) + results.push(result) + onProgress("Language preference", result.status, result.message) + } + + // Migrate autocomplete settings + if (selections.settings.autocomplete && legacySettings.autocomplete) { + onProgress("Autocomplete settings", "migrating") + const result = await migrateAutocomplete(legacySettings.autocomplete) + results.push(result) + onProgress("Autocomplete settings", result.status, result.message) + } + + return results +} + +// --------------------------------------------------------------------------- +// Cleanup +// --------------------------------------------------------------------------- + +/** + * Removes legacy data from SecretStorage, globalState, and VS Code settings. + */ +export async function clearLegacyData(context: vscode.ExtensionContext): Promise { + await context.secrets.delete(SECRET_KEY) + + const legacyStateKeys = [ + "kilo-code.allowedCommands", + "kilo-code.deniedCommands", + "kilo-code.autoApprovalEnabled", + "kilo-code.fuzzyMatchThreshold", + "kilo-code.diffEnabled", + "kilo-code.language", + "kilo-code.customModes", + "kilo-code.firstInstallCompleted", + "kilo-code.telemetrySetting", + "ghostServiceSettings", + // Fine-grained auto-approval keys (no prefix in legacy globalState) + "alwaysAllowReadOnly", + "alwaysAllowReadOnlyOutsideWorkspace", + "alwaysAllowWrite", + "alwaysAllowWriteOutsideWorkspace", + "alwaysAllowWriteProtected", + "alwaysAllowDelete", + "alwaysAllowExecute", + "alwaysAllowBrowser", + "alwaysAllowMcp", + "alwaysAllowModeSwitch", + "alwaysAllowSubtasks", + "alwaysAllowFollowupQuestions", + "followupAutoApproveTimeoutMs", + ] + for (const key of legacyStateKeys) { + await context.globalState.update(key, undefined) + } + + // Clear legacy VS Code settings registered under the "kilo-code" configuration scope. + // These are set via the old extension's contributes.configuration and persist in the + // user's settings.json even after the extension is uninstalled. + const legacyVscodeSettings = [ + "allowedCommands", + "deniedCommands", + "commandExecutionTimeout", + "commandTimeoutAllowlist", + "preventCompletionWithOpenTodos", + "vsCodeLmModelSelector", + "customStoragePath", + "enableCodeActions", + "autoImportSettingsPath", + "maximumIndexedFilesForFileSearch", + "useAgentRules", + "apiRequestTimeout", + "newTaskRequireTodos", + "enableSettingsSync", + "toolProtocol", + "debug", + ] + const cfg = vscode.workspace.getConfiguration("kilo-code") + for (const key of legacyVscodeSettings) { + await cfg.update(key, undefined, vscode.ConfigurationTarget.Global) + } +} + +// --------------------------------------------------------------------------- +// Internal — provider migration +// --------------------------------------------------------------------------- + +async function migrateProvider( + profileName: string, + settings: LegacyProviderSettings, + client: KiloClient, +): Promise { + const provider = settings.apiProvider + if (!provider) { + return { item: profileName, category: "provider", status: "error", message: "No provider type found" } + } + + if (UNSUPPORTED_PROVIDERS.has(provider)) { + return { + item: profileName, + category: "provider", + status: "warning", + message: `Provider "${provider}" is not supported in the new version`, + } + } + + const mapping = PROVIDER_MAP[provider] + if (!mapping) { + return { + item: profileName, + category: "provider", + status: "warning", + message: `Unknown provider "${provider}"`, + } + } + + const apiKey = settings[mapping.key] as string | undefined + if (!apiKey) { + return { item: profileName, category: "provider", status: "warning", message: "No API key found in profile" } + } + + // For providers that support an organization ID (e.g. Kilo Gateway), migrate using OAuth + // auth so the CLI can read accountId for org-scoped API requests. + const organizationId = mapping.organizationIdField + ? (settings[mapping.organizationIdField] as string | undefined) + : undefined + + const auth = organizationId + ? { type: "oauth" as const, access: apiKey, refresh: "", expires: 0, accountId: organizationId } + : { type: "api" as const, key: apiKey } + + await client.auth.set({ providerID: mapping.id, auth }) + + // If a custom base URL is configured, also persist it to the backend config + if (mapping.urlField) { + const url = settings[mapping.urlField] as string | undefined + if (url) { + await client.global.config.update({ + config: { provider: { [mapping.id]: { options: { apiKey, baseURL: url } } } }, + }) + } + } + + return { item: profileName, category: "provider", status: "success" } +} + +async function migrateDefaultModel(settings: LegacyProviderSettings, client: KiloClient): Promise { + const provider = settings.apiProvider + if (!provider) { + return { item: "Default model", category: "defaultModel", status: "error", message: "No provider type found" } + } + + const mapping = PROVIDER_MAP[provider] + if (!mapping) { + return { + item: "Default model", + category: "defaultModel", + status: "warning", + message: `Provider "${provider}" is not supported in the new version`, + } + } + + const modelField = mapping.modelField ?? "apiModelId" + const modelId = settings[modelField] as string | undefined + if (!modelId) { + return { item: "Default model", category: "defaultModel", status: "warning", message: "No model ID found" } + } + + await client.global.config.update({ config: { model: `${mapping.id}/${modelId}` } }) + return { item: "Default model", category: "defaultModel", status: "success" } +} + +// --------------------------------------------------------------------------- +// Internal — settings migration (auto-approval, language) +// --------------------------------------------------------------------------- + +async function migrateAutoApproval( + settings: LegacySettings, + sel: MigrationAutoApprovalSelections, + client: KiloClient, + onProgress: ProgressCallback, +): Promise { + const { + autoApprovalEnabled, + allowedCommands, + deniedCommands, + alwaysAllowReadOnly, + alwaysAllowReadOnlyOutsideWorkspace, + alwaysAllowWrite, + alwaysAllowExecute, + alwaysAllowMcp, + alwaysAllowModeSwitch, + alwaysAllowSubtasks, + } = settings + + // The master toggle acts as a global fallback for unspecified tools. + const fallback: "allow" | "ask" = autoApprovalEnabled === true ? "allow" : "ask" + + const results: MigrationResultItem[] = [] + // We collect all permission updates and apply them in one call at the end. + const permission: PermissionConfig = {} + // Track if global "allow" was already written so we skip the per-tool object update + // that would otherwise overwrite it with a narrower permission set. + let globalAllowApplied = false + + // Command rules: master toggle + allowedCommands + deniedCommands + if (sel.commandRules) { + const label = "Command rules" + onProgress(label, "migrating") + const hasCommandLists = Boolean(allowedCommands?.length || deniedCommands?.length) + if (autoApprovalEnabled === true && !hasCommandLists) { + // Global allow with no specific command rules — apply immediately using the scalar form. + // PermissionConfig is "allow" | "ask" | "deny" | { read?: ..., ... }, so a global allow + // must be the scalar string, not an object with a "*" key. + await client.global.config.update({ config: { permission: "allow" } }) + globalAllowApplied = true + } else if (hasCommandLists) { + const bashRules: PermissionObjectConfig = {} + // The legacy system matched commands as longest prefix (e.g. "npm run" matched "npm run dev"). + // The new CLI uses Wildcard.match with full command text anchored to ^ and $, so "npm run" + // would only match the literal string "npm run". Appending " *" approximates prefix semantics: + // Wildcard.match treats trailing " *" as "( .*)?", matching with or without arguments. + for (const cmd of allowedCommands ?? []) { + bashRules[cmd.trimEnd() + " *"] = "allow" + } + for (const cmd of deniedCommands ?? []) { + bashRules[cmd.trimEnd() + " *"] = "deny" + } + // alwaysAllowExecute=false must override the master toggle + bashRules["*"] = alwaysAllowExecute === true ? "allow" : alwaysAllowExecute === false ? "ask" : fallback + permission.bash = bashRules + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } + + // Read permissions + if (sel.readPermission) { + const label = "Read permission" + onProgress(label, "migrating") + if (alwaysAllowReadOnly === true) { + permission.read = "allow" + permission.glob = "allow" + permission.grep = "allow" + permission.list = "allow" + } else if (alwaysAllowReadOnly === false) { + permission.read = "ask" + } + if (alwaysAllowReadOnlyOutsideWorkspace === true) { + permission.external_directory = "allow" + } else if (alwaysAllowReadOnlyOutsideWorkspace === false) { + permission.external_directory = "ask" + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } + + // Write permissions + if (sel.writePermission) { + const label = "Write permission" + onProgress(label, "migrating") + if (alwaysAllowWrite === true) { + permission.edit = "allow" + } else if (alwaysAllowWrite === false) { + permission.edit = "ask" + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } + + // Execute permissions (bash only — command lists handled above in commandRules) + if (sel.executePermission && !sel.commandRules) { + const label = "Execute permission" + onProgress(label, "migrating") + if (alwaysAllowExecute === true) { + permission.bash = "allow" + } else if (alwaysAllowExecute === false) { + permission.bash = "ask" + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } else if (sel.executePermission) { + // executePermission selected together with commandRules — bash rules already built above, + // just record the result item + results.push({ item: "Execute permission", category: "settings", status: "success" }) + } + + // MCP / skill permissions + if (sel.mcpPermission) { + const label = "MCP permission" + onProgress(label, "migrating") + if (alwaysAllowMcp === true) { + permission.skill = "allow" + } else if (alwaysAllowMcp === false) { + permission.skill = "ask" + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } + + // Task / subtask permissions + if (sel.taskPermission) { + const label = "Task permission" + onProgress(label, "migrating") + if (alwaysAllowModeSwitch === true || alwaysAllowSubtasks === true) { + permission.task = "allow" + } else if (alwaysAllowModeSwitch === false && alwaysAllowSubtasks === false) { + permission.task = "ask" + } + results.push({ item: label, category: "settings", status: "success" }) + onProgress(label, "success") + } + + // Only write the per-tool object form if global allow wasn't already applied — + // writing an object after "allow" would narrow permissions to only the listed tools. + if (!globalAllowApplied && Object.keys(permission).length > 0) { + await client.global.config.update({ config: { permission } }) + } + + return results +} + +async function migrateAutocomplete(settings: LegacyAutocompleteSettings): Promise { + try { + const config = vscode.workspace.getConfiguration("kilo-code.new.autocomplete") + if (settings.enableAutoTrigger !== undefined) { + await config.update("enableAutoTrigger", settings.enableAutoTrigger, vscode.ConfigurationTarget.Global) + } + if (settings.enableSmartInlineTaskKeybinding !== undefined) { + await config.update( + "enableSmartInlineTaskKeybinding", + settings.enableSmartInlineTaskKeybinding, + vscode.ConfigurationTarget.Global, + ) + } + if (settings.enableChatAutocomplete !== undefined) { + await config.update("enableChatAutocomplete", settings.enableChatAutocomplete, vscode.ConfigurationTarget.Global) + } + return { item: "Autocomplete settings", category: "settings", status: "success" } + } catch (err) { + return { + item: "Autocomplete settings", + category: "settings", + status: "error", + message: err instanceof Error ? err.message : String(err), + } + } +} + +// Maps legacy locale codes to their new-extension equivalents. +// Legacy used IETF BCP-47 tags (zh-CN, pt-BR) while the new extension uses short codes. +// Entries absent from this map have no equivalent in the new extension. +const LEGACY_LOCALE_MAP: Record = { + // Direct matches + en: "en", + de: "de", + es: "es", + fr: "fr", + ja: "ja", + ko: "ko", + pl: "pl", + ru: "ru", + ar: "ar", + th: "th", + da: "da", + no: "no", + bs: "bs", + // Format changes + "zh-CN": "zh", + "zh-TW": "zht", + "pt-BR": "br", +} + +async function migrateLanguage(language: string): Promise { + const mapped = LEGACY_LOCALE_MAP[language] + if (!mapped) { + return { + item: "Language preference", + category: "settings", + status: "warning", + message: `Language "${language}" is not supported in the new version`, + } + } + try { + const config = vscode.workspace.getConfiguration("kilo-code.new") + await config.update("language", mapped, vscode.ConfigurationTarget.Global) + return { item: "Language preference", category: "settings", status: "success" } + } catch (err) { + return { + item: "Language preference", + category: "settings", + status: "error", + message: err instanceof Error ? err.message : String(err), + } + } +} + +// --------------------------------------------------------------------------- +// Internal — MCP conversion (legacy → McpServerConfig) +// --------------------------------------------------------------------------- + +function convertMcpServer(server: LegacyMcpServer): McpLocalConfig | McpRemoteConfig | null { + if (server.type === "sse" || server.type === "streamable-http") { + if (!server.url) return null + return { type: "remote", url: server.url, headers: server.headers } + } + // Default: stdio + if (!server.command) return null + const command = server.args ? [server.command, ...server.args] : [server.command] + return { + type: "local", + command, + environment: server.env, + ...(server.timeout !== undefined && { timeout: server.timeout }), + } +} + +// --------------------------------------------------------------------------- +// Internal — custom mode conversion (legacy → AgentConfig) +// --------------------------------------------------------------------------- + +// Group name → CLI permission key (mirrors ModesMigrator.convertPermissions in the CLI) +const GROUP_TO_PERMISSION: Record = { + read: "read", + edit: "edit", + browser: "bash", + command: "bash", + mcp: "skill", +} +const ALL_MODE_PERMISSIONS = ["read", "edit", "bash", "skill"] + +function convertCustomModePermissions(groups: LegacyCustomMode["groups"]): PermissionConfig { + const permission: Record = {} + const allowed = new Set() + + for (const group of groups) { + const groupName = typeof group === "string" ? group : group[0] + const groupConfig = typeof group === "string" ? undefined : group[1] + const permKey = GROUP_TO_PERMISSION[groupName] ?? groupName + allowed.add(permKey) + + const newValue = groupConfig?.fileRegex ? { [groupConfig.fileRegex]: "allow", "*": "deny" } : "allow" + + // Multiple legacy groups can map to the same permission key (browser + command → bash). + // Merge rules so neither overwrites the other: + // - if either side is "allow", the key is fully allowed + // - if both sides are objects, merge their pattern maps + const existing = permission[permKey] + if (existing === undefined) { + permission[permKey] = newValue + } else if (existing === "allow" || newValue === "allow") { + permission[permKey] = "allow" + } else if (typeof existing === "object" && typeof newValue === "object") { + permission[permKey] = { ...existing, ...newValue } + } else { + permission[permKey] = newValue + } + } + + // Explicitly deny permissions not in the groups (CLI defaults to "ask" for missing ones) + for (const perm of ALL_MODE_PERMISSIONS) { + if (!allowed.has(perm)) { + permission[perm] = "deny" + } + } + + return permission as PermissionConfig +} + +function convertCustomMode(mode: LegacyCustomMode): AgentConfig { + const prompt = [mode.roleDefinition, mode.customInstructions].filter(Boolean).join("\n\n") + return { + mode: "primary", + description: mode.customInstructions ?? mode.roleDefinition?.slice(0, 120), + prompt, + permission: convertCustomModePermissions(mode.groups), + } +} + +// --------------------------------------------------------------------------- +// Internal — reading legacy data from storage +// --------------------------------------------------------------------------- + +async function readLegacyProviderProfiles(context: vscode.ExtensionContext): Promise { + const raw = await context.secrets.get(SECRET_KEY) + if (!raw) return null + try { + const parsed = JSON.parse(raw) as Record + if (!parsed.apiConfigs || typeof parsed.apiConfigs !== "object") return null + return parsed as unknown as LegacyProviderProfiles + } catch { + return null + } +} + +async function readLegacyMcpSettings(context: vscode.ExtensionContext): Promise { + const filePath = vscode.Uri.joinPath(context.globalStorageUri, "settings", "mcp_settings.json") + const bytes = await vscode.workspace.fs.readFile(filePath).then( + (b) => b, + () => null, + ) + if (!bytes) return null + try { + const parsed = JSON.parse(Buffer.from(bytes).toString("utf8")) as Record + if (!parsed.mcpServers || typeof parsed.mcpServers !== "object") return null + return parsed as unknown as LegacyMcpSettings + } catch { + return null + } +} + +async function readLegacyCustomModes(context: vscode.ExtensionContext): Promise { + const filePath = vscode.Uri.joinPath(context.globalStorageUri, "settings", "custom_modes.yaml") + const bytes = await vscode.workspace.fs.readFile(filePath).then( + (b) => b, + () => null, + ) + if (!bytes) return null + const text = Buffer.from(bytes).toString("utf8") + return parseCustomModesYaml(text) +} + +function readLegacySettings(context: vscode.ExtensionContext): LegacySettings { + const raw = context.globalState.get>("ghostServiceSettings") + const autocomplete: LegacyAutocompleteSettings | undefined = + raw && typeof raw === "object" + ? { + enableAutoTrigger: raw.enableAutoTrigger as boolean | undefined, + enableSmartInlineTaskKeybinding: raw.enableSmartInlineTaskKeybinding as boolean | undefined, + enableChatAutocomplete: raw.enableChatAutocomplete as boolean | undefined, + } + : undefined + + return { + autoApprovalEnabled: context.globalState.get("kilo-code.autoApprovalEnabled"), + allowedCommands: context.globalState.get("kilo-code.allowedCommands"), + deniedCommands: context.globalState.get("kilo-code.deniedCommands"), + // Fine-grained auto-approval — stored without prefix in legacy globalState + alwaysAllowReadOnly: context.globalState.get("alwaysAllowReadOnly"), + alwaysAllowReadOnlyOutsideWorkspace: context.globalState.get("alwaysAllowReadOnlyOutsideWorkspace"), + alwaysAllowWrite: context.globalState.get("alwaysAllowWrite"), + alwaysAllowExecute: context.globalState.get("alwaysAllowExecute"), + alwaysAllowMcp: context.globalState.get("alwaysAllowMcp"), + alwaysAllowModeSwitch: context.globalState.get("alwaysAllowModeSwitch"), + alwaysAllowSubtasks: context.globalState.get("alwaysAllowSubtasks"), + language: context.globalState.get("kilo-code.language"), + autocomplete: hasAutocompleteData(autocomplete) ? autocomplete : undefined, + } +} + +function hasAutocompleteData(s: LegacyAutocompleteSettings | undefined): s is LegacyAutocompleteSettings { + if (!s) return false + return ( + s.enableAutoTrigger !== undefined || + s.enableSmartInlineTaskKeybinding !== undefined || + s.enableChatAutocomplete !== undefined + ) +} + +/** + * Minimal YAML parser for the custom_modes.yaml format. + * Tries JSON first (some legacy versions stored JSON), then parses the simple + * YAML structure manually to avoid a runtime dependency on a YAML library. + */ +// Strip surrounding single or double quotes from a YAML scalar value +function stripYamlQuotes(value: string): string { + return value.replace(/^(['"])(.*)\1$/, "$2") +} + +function parseCustomModesYaml(text: string): LegacyCustomMode[] | null { + // Try JSON first + const jsonResult = (() => { + try { + const parsed = JSON.parse(text) as { customModes?: LegacyCustomMode[] } + return parsed.customModes ?? null + } catch { + return null + } + })() + if (jsonResult) return jsonResult + + // Parse the simple YAML shape: + // customModes: + // - slug: xxx + // name: xxx + // roleDefinition: | + // ... + // groups: + // - read + const modes: LegacyCustomMode[] = [] + const lines = text.split("\n") + let inModes = false + let current: Partial | null = null + // Track which block scalar field is currently being collected + let blockField: "roleDefinition" | "customInstructions" | null = null + let inGroups = false + let blockLines: string[] = [] + + const flush = () => { + if (current?.slug && current?.name) { + if (blockField && blockLines.length > 0) { + current[blockField] = blockLines.join("\n").trim() + } + modes.push({ groups: [], ...current } as LegacyCustomMode) + } + current = null + blockField = null + inGroups = false + blockLines = [] + } + + for (const rawLine of lines) { + if (!inModes) { + if (rawLine.trim() === "customModes:") inModes = true + continue + } + + if (/^ - slug: /.test(rawLine)) { + flush() + current = { slug: stripYamlQuotes(rawLine.replace(/^ - slug: /, "").trim()), groups: [] } + continue + } + + if (!current) continue + + if (/^ name: /.test(rawLine)) { + current.name = stripYamlQuotes(rawLine.replace(/^ name: /, "").trim()) + continue + } + + // Block scalar fields (roleDefinition, customInstructions) with | or > + const blockMatch = rawLine.match(/^ (roleDefinition|customInstructions): [|>]/) + if (blockMatch) { + // Flush any previously open block + if (blockField && blockLines.length > 0) { + current[blockField] = blockLines.join("\n").trim() + } + blockField = blockMatch[1] as "roleDefinition" | "customInstructions" + inGroups = false + blockLines = [] + continue + } + + // Single-line scalar fields + if (/^ roleDefinition: /.test(rawLine) && !blockField) { + current.roleDefinition = stripYamlQuotes(rawLine.replace(/^ roleDefinition: /, "").trim()) + continue + } + + if (/^ customInstructions: /.test(rawLine) && !blockField) { + current.customInstructions = stripYamlQuotes(rawLine.replace(/^ customInstructions: /, "").trim()) + continue + } + + if (/^ whenToUse: /.test(rawLine) && !blockField) { + current.whenToUse = stripYamlQuotes(rawLine.replace(/^ whenToUse: /, "").trim()) + continue + } + + if (/^ description: /.test(rawLine) && !blockField) { + current.description = stripYamlQuotes(rawLine.replace(/^ description: /, "").trim()) + continue + } + + // Continuation lines of an open block scalar + if (blockField) { + if (/^ /.test(rawLine)) { + blockLines.push(rawLine.replace(/^ /, "")) + continue + } + // Block ended — flush and fall through to process this line + current[blockField] = blockLines.join("\n").trim() + blockField = null + blockLines = [] + } + + if (/^ groups:/.test(rawLine)) { + inGroups = true + current.groups = [] + continue + } + + if (inGroups && /^ - /.test(rawLine)) { + const group = stripYamlQuotes(rawLine.replace(/^ - /, "").trim()) + current.groups = [...(current.groups ?? []), group] + continue + } + + if (inGroups && !/^ /.test(rawLine)) { + inGroups = false + } + } + + flush() + return modes.length > 0 ? modes : null +} + +// --------------------------------------------------------------------------- +// Internal — building display lists for the wizard +// --------------------------------------------------------------------------- + +function buildProviderList(profiles: LegacyProviderProfiles | null): MigrationProviderInfo[] { + if (!profiles?.apiConfigs) return [] + + return Object.entries(profiles.apiConfigs).map(([profileName, settings]) => { + const provider = settings.apiProvider ?? "unknown" + const mapping = PROVIDER_MAP[provider] + const unsupported = UNSUPPORTED_PROVIDERS.has(provider) + + const modelField = mapping?.modelField ?? "apiModelId" + const model = settings[modelField] as string | undefined + + const hasApiKey = mapping ? Boolean(settings[mapping.key]) : false + + return { + profileName, + provider, + model, + hasApiKey, + supported: Boolean(mapping) && !unsupported, + newProviderName: mapping?.name, + } + }) +} + +function buildMcpServerList(settings: LegacyMcpSettings | null): MigrationMcpServerInfo[] { + if (!settings?.mcpServers) return [] + return Object.entries(settings.mcpServers) + .filter(([, server]) => !server.disabled) + .map(([name, server]) => ({ name, type: server.type ?? "stdio" })) +} + +function buildCustomModeList(modes: LegacyCustomMode[] | null): MigrationCustomModeInfo[] { + if (!modes) return [] + return modes.filter((m) => !DEFAULT_MODE_SLUGS.has(m.slug)).map((m) => ({ name: m.name, slug: m.slug })) +} + +function resolveDefaultModel(profiles: LegacyProviderProfiles | null): { provider: string; model: string } | undefined { + if (!profiles?.currentApiConfigName) return undefined + const active = profiles.apiConfigs[profiles.currentApiConfigName] + if (!active?.apiProvider) return undefined + const mapping = PROVIDER_MAP[active.apiProvider] + if (!mapping) return undefined + const modelField = mapping.modelField ?? "apiModelId" + const model = active[modelField] as string | undefined + if (!model) return undefined + return { provider: mapping.name, model } +} diff --git a/packages/kilo-vscode/src/legacy-migration/provider-mapping.ts b/packages/kilo-vscode/src/legacy-migration/provider-mapping.ts new file mode 100644 index 00000000000..817cdeb9775 --- /dev/null +++ b/packages/kilo-vscode/src/legacy-migration/provider-mapping.ts @@ -0,0 +1,264 @@ +/** + * legacy-migration - Maps legacy apiProvider values to new provider IDs and key fields. + * + * The legacy extension used flat per-provider key names (e.g. apiKey, openRouterApiKey). + * The new CLI backend uses a per-provider auth endpoint (PUT /auth/:providerId). + */ + +export interface ProviderMapping { + /** New provider ID for the auth endpoint (PUT /auth/:id) */ + id: string + /** Field name in LegacyProviderSettings holding the primary API key */ + key: string + /** Display name for the provider in the wizard UI */ + name: string + /** Field holding model ID (defaults to "apiModelId") */ + modelField?: string + /** Field holding custom base URL (to also store in config) */ + urlField?: string + /** Field holding an organization/account ID (used for OAuth-style auth) */ + organizationIdField?: string +} + +/** + * Maps legacy `apiProvider` values → new provider info. + * Providers absent from this map are flagged as unsupported. + */ +export const PROVIDER_MAP: Record = { + anthropic: { + id: "anthropic", + key: "apiKey", + name: "Anthropic", + }, + openrouter: { + id: "openrouter", + key: "openRouterApiKey", + name: "OpenRouter", + modelField: "openRouterModelId", + }, + openai: { + id: "openai-compatible", + key: "openAiApiKey", + name: "OpenAI (Compatible)", + modelField: "openAiModelId", + urlField: "openAiBaseUrl", + }, + "openai-native": { + id: "openai", + key: "openAiNativeApiKey", + name: "OpenAI", + urlField: "openAiNativeBaseUrl", + }, + "openai-responses": { + id: "openai", + key: "openAiApiKey", + name: "OpenAI", + modelField: "openAiModelId", + }, + gemini: { + id: "google", + key: "geminiApiKey", + name: "Google Gemini", + urlField: "googleGeminiBaseUrl", + }, + vertex: { + id: "google-vertex", + key: "vertexJsonCredentials", + name: "Google Vertex AI", + }, + bedrock: { + id: "amazon-bedrock", + key: "awsAccessKey", + name: "AWS Bedrock", + }, + deepseek: { + id: "deepseek", + key: "deepSeekApiKey", + name: "DeepSeek", + urlField: "deepSeekBaseUrl", + }, + mistral: { + id: "mistral", + key: "mistralApiKey", + name: "Mistral", + }, + groq: { + id: "groq", + key: "groqApiKey", + name: "Groq", + }, + xai: { + id: "xai", + key: "xaiApiKey", + name: "xAI", + }, + fireworks: { + id: "fireworks", + key: "fireworksApiKey", + name: "Fireworks", + }, + featherless: { + id: "featherless", + key: "featherlessApiKey", + name: "Featherless", + }, + cerebras: { + id: "cerebras", + key: "cerebrasApiKey", + name: "Cerebras", + }, + sambanova: { + id: "sambanova", + key: "sambaNovaApiKey", + name: "SambaNova", + }, + ollama: { + id: "ollama", + key: "ollamaApiKey", + name: "Ollama", + modelField: "ollamaModelId", + urlField: "ollamaBaseUrl", + }, + lmstudio: { + id: "lmstudio", + key: "lmStudioBaseUrl", + name: "LM Studio", + modelField: "lmStudioModelId", + urlField: "lmStudioBaseUrl", + }, + kilocode: { + id: "kilo", + key: "kilocodeToken", + name: "Kilo (Gateway)", + modelField: "kilocodeModel", + organizationIdField: "kilocodeOrganizationId", + }, + litellm: { + id: "litellm", + key: "litellmApiKey", + name: "LiteLLM", + modelField: "litellmModelId", + urlField: "litellmBaseUrl", + }, + deepinfra: { + id: "deepinfra", + key: "deepInfraApiKey", + name: "DeepInfra", + modelField: "deepInfraModelId", + urlField: "deepInfraBaseUrl", + }, + chutes: { + id: "chutes", + key: "chutesApiKey", + name: "Chutes", + }, + baseten: { + id: "baseten", + key: "basetenApiKey", + name: "Baseten", + }, + corethink: { + id: "corethink", + key: "corethinkApiKey", + name: "Corethink", + }, + unbound: { + id: "unbound", + key: "unboundApiKey", + name: "Unbound", + modelField: "unboundModelId", + }, + requesty: { + id: "requesty", + key: "requestyApiKey", + name: "Requesty", + modelField: "requestyModelId", + urlField: "requestyBaseUrl", + }, + huggingface: { + id: "huggingface", + key: "huggingFaceApiKey", + name: "Hugging Face", + modelField: "huggingFaceModelId", + }, + "io-intelligence": { + id: "io-intelligence", + key: "ioIntelligenceApiKey", + name: "IO Intelligence", + modelField: "ioIntelligenceModelId", + }, + "vercel-ai-gateway": { + id: "vercel-ai-gateway", + key: "vercelAiGatewayApiKey", + name: "Vercel AI Gateway", + modelField: "vercelAiGatewayModelId", + }, + zai: { + id: "zai", + key: "zaiApiKey", + name: "Z.ai", + }, + moonshot: { + id: "moonshot", + key: "moonshotApiKey", + name: "Moonshot", + urlField: "moonshotBaseUrl", + }, + doubao: { + id: "doubao", + key: "doubaoApiKey", + name: "Doubao", + urlField: "doubaoBaseUrl", + }, + minimax: { + id: "minimax", + key: "minimaxApiKey", + name: "MiniMax", + urlField: "minimaxBaseUrl", + }, + ovhcloud: { + id: "ovhcloud", + key: "ovhCloudAiEndpointsApiKey", + name: "OVHcloud AI Endpoints", + modelField: "ovhCloudAiEndpointsModelId", + urlField: "ovhCloudAiEndpointsBaseUrl", + }, + inception: { + id: "inception", + key: "inceptionLabsApiKey", + name: "Inception Labs", + modelField: "inceptionLabsModelId", + urlField: "inceptionLabsBaseUrl", + }, + "sap-ai-core": { + id: "sap-ai-core", + key: "sapAiCoreServiceKey", + name: "SAP AI Core", + }, + synthetic: { + id: "synthetic", + key: "syntheticApiKey", + name: "Synthetic", + }, +} + +/** Providers that have no equivalent in the new CLI backend */ +export const UNSUPPORTED_PROVIDERS = new Set([ + "fake-ai", + "human-relay", + "vscode-lm", + "claude-code", + "openai-codex", + "qwen-code", + "virtual-quota-fallback", + "glama", + "roo", + "nano-gpt", + "poe", + "aihubmix", + "apertis", + "zenmux", +]) + +/** Built-in default mode slugs that should not be migrated */ +export const DEFAULT_MODE_SLUGS = new Set(["code", "build", "architect", "ask", "debug", "orchestrator", "review"]) diff --git a/packages/kilo-vscode/src/services/cli-backend/server-manager.ts b/packages/kilo-vscode/src/services/cli-backend/server-manager.ts index 47bb423b927..3e1afb44612 100644 --- a/packages/kilo-vscode/src/services/cli-backend/server-manager.ts +++ b/packages/kilo-vscode/src/services/cli-backend/server-manager.ts @@ -68,7 +68,7 @@ export class ServerManager { KILO_SERVER_PASSWORD: password, KILO_CLIENT: "vscode", KILO_ENABLE_QUESTION_TOOL: "true", - KILOCODE_FEATURE: "vscode-extension", // kilocode_change - feature tracking + KILOCODE_FEATURE: "vscode-extension", KILO_TELEMETRY_LEVEL: vscode.env.isTelemetryEnabled ? "all" : "off", KILO_APP_NAME: "kilo-code", KILO_EDITOR_NAME: vscode.env.appName, @@ -130,7 +130,7 @@ export class ServerManager { private getCliPath(): string { // Always use the bundled binary from the extension directory - const binName = process.platform === "win32" ? "kilo.exe" : "kilo" // kilocode_change + const binName = process.platform === "win32" ? "kilo.exe" : "kilo" const cliPath = path.join(this.context.extensionPath, "bin", binName) console.log("[Kilo New] ServerManager: 📦 Using CLI path:", cliPath) return cliPath diff --git a/packages/kilo-vscode/src/webview-html-utils.ts b/packages/kilo-vscode/src/webview-html-utils.ts index 629320dfa06..2acfb9b7f73 100644 --- a/packages/kilo-vscode/src/webview-html-utils.ts +++ b/packages/kilo-vscode/src/webview-html-utils.ts @@ -27,7 +27,7 @@ export function buildCspString(cspSource: string, nonce: string, port?: number): `style-src 'unsafe-inline' ${cspSource}`, `script-src 'nonce-${nonce}' 'wasm-unsafe-eval'`, `font-src ${cspSource}`, - `connect-src ${connectSrc}`, + `connect-src ${cspSource} ${connectSrc}`, `img-src ${cspSource} data: https:`, ] return joinCspDirectives(directives) diff --git a/packages/kilo-vscode/tests/unit/agent-manager-i18n-split.test.ts b/packages/kilo-vscode/tests/unit/agent-manager-i18n-split.test.ts index b66c809c6dc..b51354ae41a 100644 --- a/packages/kilo-vscode/tests/unit/agent-manager-i18n-split.test.ts +++ b/packages/kilo-vscode/tests/unit/agent-manager-i18n-split.test.ts @@ -72,6 +72,12 @@ const appLocales = { bs: appBs, } +function placeholders(text: string): string[] { + return Array.from(text.matchAll(/\{\{\s*([\w.]+)\s*\}\}/g)) + .flatMap((match) => (match[1] ? [match[1]] : [])) + .sort() +} + describe("Agent Manager i18n split", () => { it("keeps agent manager keys out of general locale dictionaries", () => { for (const [locale, dict] of Object.entries(appLocales)) { @@ -92,6 +98,35 @@ describe("Agent Manager i18n split", () => { } }) + it("keeps every agent manager locale keyset aligned with english", () => { + const baseKeys = Object.keys(amEn) + + for (const [locale, dict] of Object.entries(locales)) { + const keySet = new Set(Object.keys(dict)) + const missing = baseKeys.filter((key) => !keySet.has(key)) + const extra = Array.from(keySet).filter((key) => !(key in amEn)) + + expect(missing, `locale ${locale} is missing agent manager keys`).toEqual([]) + expect(extra, `locale ${locale} has unexpected agent manager keys`).toEqual([]) + } + }) + + it("keeps interpolation placeholders aligned with english", () => { + for (const [locale, dict] of Object.entries(locales)) { + if (locale === "en") continue + + for (const [key, value] of Object.entries(amEn)) { + const localized = (dict as Record)[key] + expect(localized, `missing key ${key} in locale ${locale}`).toBeDefined() + if (!localized) continue + + const baseVars = placeholders(value) + const localeVars = placeholders(localized) + expect(localeVars, `placeholder mismatch for ${key} in locale ${locale}`).toEqual(baseVars) + } + } + }) + it("contains required core keys in every locale", () => { const required = [ "agentManager.local", diff --git a/packages/kilo-vscode/tests/unit/webview-html.test.ts b/packages/kilo-vscode/tests/unit/webview-html.test.ts index 2b930f163fb..465588e7cde 100644 --- a/packages/kilo-vscode/tests/unit/webview-html.test.ts +++ b/packages/kilo-vscode/tests/unit/webview-html.test.ts @@ -67,6 +67,11 @@ describe("buildCspString", () => { expect(result).not.toContain(":*") }) + it("includes cspSource in connect-src for source map loading", () => { + const result = buildCspString(cspSource, nonce) + expect(result).toMatch(new RegExp(`connect-src\\s+${cspSource.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}`)) + }) + it("joins directives with semicolons", () => { const result = buildCspString(cspSource, nonce) const parts = result.split(";") diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts b/packages/kilo-vscode/tests/visual-regression.spec.ts new file mode 100644 index 00000000000..36e5f071725 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts @@ -0,0 +1,77 @@ +import { test, expect, type Page } from "@playwright/test" +import { platform } from "node:os" + +const IS_DARWIN = platform() === "darwin" + +// Screenshot baselines are captured on Linux CI — font rendering and anti-aliasing +// differ on macOS, which causes false-positive diffs. Skip the entire suite there. +if (IS_DARWIN) { + console.warn("Visual regression tests must be run on CI, skipping on local macOS.") + test.skip() +} + +type Story = { + id: string + title: string + name: string +} + +type StoriesIndex = { + stories?: Record + entries?: Record +} + +const STORYBOOK_URL = "http://localhost:6007" + +// Fetched once per worker process — cheap HTTP call to the already-running Storybook +async function fetchStories(): Promise { + const res = await fetch(`${STORYBOOK_URL}/index.json`).catch(() => fetch(`${STORYBOOK_URL}/stories.json`)) + if (!res.ok) throw new Error(`Storybook index fetch failed: ${res.status} ${res.statusText}`) + const data = (await res.json()) as StoriesIndex + const map = data.entries ?? data.stories ?? {} + return Object.values(map).filter((s) => s.id && !s.id.endsWith("--docs")) +} + +async function disableAnimations(page: Page) { + await page.addStyleTag({ + content: ` + *, *::before, *::after { + animation-duration: 0s !important; + animation-delay: 0s !important; + transition-duration: 0s !important; + transition-delay: 0s !important; + } + `, + }) +} + +// Stories to skip from visual regression (add IDs here if needed) +const SKIP = new Set([]) + +// Use test.describe + beforeAll to avoid top-level await which breaks +// on Node.js versions with strict ESM/CJS boundaries. +test.describe("Visual Regression", () => { + let stories: Story[] = [] + + test.beforeAll(async () => { + if (IS_DARWIN) return + stories = (await fetchStories()).filter((s) => !SKIP.has(s.id)) + }) + + test("all stories", async ({ page }) => { + if (IS_DARWIN) return + for (const story of stories) { + // Use kilo-vscode theme by default (matched to the preview initialGlobals) + await page.goto( + `/iframe.html?id=${story.id}&viewMode=story&globals=colorScheme:dark;theme:kilo-vscode;vscodeTheme:dark-modern`, + { waitUntil: "load" }, + ) + await disableAnimations(page) + await page.waitForSelector("#storybook-root *", { state: "attached" }) + + const [component, variant] = story.id.split("--") + const root = page.locator("#storybook-root") + await expect(root).toHaveScreenshot([component!, `${variant}.png`]) + } + }) +}) diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/bash-with-permission-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/bash-with-permission-chromium-linux.png new file mode 100644 index 00000000000..44ab459e0a2 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/bash-with-permission-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:04332222bf7bf3680954f967414f93e9e3d03747961fada79cd32d4a5e2a1431 +size 10279 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-busy-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-busy-chromium-linux.png new file mode 100644 index 00000000000..116b32df4ce --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-busy-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee4898a628110edf572fa27433bbb905d260225be0dd2154ccdfd4e4a2ea4c1e +size 4415 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-idle-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-idle-chromium-linux.png new file mode 100644 index 00000000000..bb29a832f34 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/chat-idle-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4b6d383088e69f94aeed3e9291092d1278f8346b2d50889bd83ecc72db5d13b7 +size 2846 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/glob-with-permission-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/glob-with-permission-chromium-linux.png new file mode 100644 index 00000000000..8b5892592b8 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/glob-with-permission-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b1c5266bca40764f48d0cdefa3398083708ed7deb354acf8a5a296f9f9e0b2a6 +size 9005 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png new file mode 100644 index 00000000000..544a3f13dd5 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/inline-question-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e92994ecc3e78cc5dd1a465b93a049e877ca30cc00a285deb4628cff287eba7b +size 28275 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/multiple-tool-calls-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/multiple-tool-calls-chromium-linux.png new file mode 100644 index 00000000000..60ef12e51a0 --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/multiple-tool-calls-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd8a53356f0aa0df5c07246296dc20273f5380a012cd579885b1974e3aeb99e1 +size 8496 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/permission-dock-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/permission-dock-chromium-linux.png new file mode 100644 index 00000000000..ed03cefc81b --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/permission-dock-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fa7bddaa15cf80565ef5b639bfe2de8d2f373019da4b72210c8ea82aaf47913f +size 10384 diff --git a/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/tool-cards-chromium-linux.png b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/tool-cards-chromium-linux.png new file mode 100644 index 00000000000..5112b15c21e --- /dev/null +++ b/packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/composite-webview/tool-cards-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64ff66248b1c07209757eb6e27ccac4967650b144317ee21076ba82c129bc17b +size 8846 diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ar.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ar.ts index b9aebc8dd21..6a2a346fbd9 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ar.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ar.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "إرسال إلى الدردشة", "agentManager.review.collapsedOnly": "{{count}} مطوي", "agentManager.review.collapsedWithLarge": "{{collapsed}} مطوي، {{large}} كبير", + "agentManager.review.largeFileCollapsed": "ملف كبير (مطوي)", + "agentManager.review.endOfLongDiff": "لقد وصلت إلى النهاية!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "طلب سحب", "agentManager.import.pastePrUrl": "الصق رابط PR...", "agentManager.import.open": "فتح", "agentManager.import.branches": "الفروع", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/br.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/br.ts index aefde201f8d..f3cef50bd71 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/br.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/br.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "Enviar para o chat", "agentManager.review.collapsedOnly": "{{count}} recolhidos", "agentManager.review.collapsedWithLarge": "{{collapsed}} recolhidos, {{large}} grandes", + "agentManager.review.largeFileCollapsed": "Arquivo grande (recolhido)", + "agentManager.review.endOfLongDiff": "Você chegou ao fim!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Solicitação de extração", "agentManager.import.pastePrUrl": "Cole a URL do PR...", "agentManager.import.open": "Abrir", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/bs.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/bs.ts index 34f8e3a8133..7f06827a885 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/bs.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/bs.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "Pošalji u chat", "agentManager.review.collapsedOnly": "{{count}} sažeto", "agentManager.review.collapsedWithLarge": "{{collapsed}} sažeto, {{large}} velikih", + "agentManager.review.largeFileCollapsed": "Velika datoteka (skupljeno)", + "agentManager.review.endOfLongDiff": "Stigli ste do kraja!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Zahtjev za povlačenje", "agentManager.import.pastePrUrl": "Zalijepite PR URL...", "agentManager.import.open": "Otvori", "agentManager.import.branches": "Branchevi", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/da.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/da.ts index 8237d1ace03..caa5984cb6d 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/da.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/da.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "Send til chat", "agentManager.review.collapsedOnly": "{{count}} foldet sammen", "agentManager.review.collapsedWithLarge": "{{collapsed}} foldet sammen, {{large}} store", + "agentManager.review.largeFileCollapsed": "Stor fil (kollapset)", + "agentManager.review.endOfLongDiff": "Du er nået til slutningen!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Fletteanmodning", "agentManager.import.pastePrUrl": "Indsæt PR URL...", "agentManager.import.open": "Åbn", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/de.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/de.ts index 843b30aff75..fa60f42a776 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/de.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/de.ts @@ -128,8 +128,10 @@ export const dict = { "agentManager.review.sendToChat": "An Chat senden", "agentManager.review.collapsedOnly": "{{count}} eingeklappt", "agentManager.review.collapsedWithLarge": "{{collapsed}} eingeklappt, {{large}} groß", + "agentManager.review.largeFileCollapsed": "Große Datei (zugeklappt)", + "agentManager.review.endOfLongDiff": "Du hast das Ende erreicht!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Zusammenführungsanfrage", "agentManager.import.pastePrUrl": "PR-URL einfügen...", "agentManager.import.open": "Öffnen", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/es.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/es.ts index 2cc665e3a02..be8727625b4 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/es.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/es.ts @@ -128,8 +128,10 @@ export const dict = { "agentManager.review.sendToChat": "Enviar al chat", "agentManager.review.collapsedOnly": "{{count}} contraídos", "agentManager.review.collapsedWithLarge": "{{collapsed}} contraídos, {{large}} grandes", + "agentManager.review.largeFileCollapsed": "Archivo grande (contraído)", + "agentManager.review.endOfLongDiff": "¡Has llegado al final!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Solicitud de extracción", "agentManager.import.pastePrUrl": "Pegar URL del PR...", "agentManager.import.open": "Abrir", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/fr.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/fr.ts index 35beaf758df..9b9c84e594f 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/fr.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/fr.ts @@ -129,8 +129,10 @@ export const dict = { "agentManager.review.sendToChat": "Envoyer au chat", "agentManager.review.collapsedOnly": "{{count}} repliés", "agentManager.review.collapsedWithLarge": "{{collapsed}} repliés, {{large}} volumineux", + "agentManager.review.largeFileCollapsed": "Fichier volumineux (réduit)", + "agentManager.review.endOfLongDiff": "Vous êtes arrivé à la fin !", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Demande d'extraction", "agentManager.import.pastePrUrl": "Coller l'URL du PR...", "agentManager.import.open": "Ouvrir", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ja.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ja.ts index 7abf7d8872b..17060e4143c 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ja.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ja.ts @@ -129,8 +129,10 @@ export const dict = { "agentManager.review.sendToChat": "チャットに送信", "agentManager.review.collapsedOnly": "{{count}} 件折りたたみ", "agentManager.review.collapsedWithLarge": "{{collapsed}} 件折りたたみ、{{large}} 件がサイズ大", + "agentManager.review.largeFileCollapsed": "大きなファイル (折りたたみ済み)", + "agentManager.review.endOfLongDiff": "最後まで到達しました!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "プルリクエスト", "agentManager.import.pastePrUrl": "PR URLを貼り付け...", "agentManager.import.open": "開く", "agentManager.import.branches": "ブランチ", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ko.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ko.ts index b526697468b..09102636015 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ko.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ko.ts @@ -128,8 +128,10 @@ export const dict = { "agentManager.review.sendToChat": "채팅으로 보내기", "agentManager.review.collapsedOnly": "{{count}}개 접힘", "agentManager.review.collapsedWithLarge": "{{collapsed}}개 접힘, {{large}}개 대용량", + "agentManager.review.largeFileCollapsed": "큰 파일 (접힘)", + "agentManager.review.endOfLongDiff": "끝까지 확인하셨습니다!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "풀 리퀘스트", "agentManager.import.pastePrUrl": "PR URL 붙여넣기...", "agentManager.import.open": "열기", "agentManager.import.branches": "브랜치", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/no.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/no.ts index 288a29d9f3d..3658a9e941a 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/no.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/no.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "Send til chat", "agentManager.review.collapsedOnly": "{{count}} kollapset", "agentManager.review.collapsedWithLarge": "{{collapsed}} kollapset, {{large}} store", + "agentManager.review.largeFileCollapsed": "Stor fil (kollapset)", + "agentManager.review.endOfLongDiff": "Du har nådd slutten!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Fletteforespørsel", "agentManager.import.pastePrUrl": "Lim inn PR URL...", "agentManager.import.open": "Åpne", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/pl.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/pl.ts index 4e4f0b70e3f..e1f74a58ac8 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/pl.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/pl.ts @@ -128,8 +128,10 @@ export const dict = { "agentManager.review.sendToChat": "Wyślij do czatu", "agentManager.review.collapsedOnly": "{{count}} zwiniętych", "agentManager.review.collapsedWithLarge": "{{collapsed}} zwiniętych, {{large}} dużych", + "agentManager.review.largeFileCollapsed": "Duży plik (zwinięty)", + "agentManager.review.endOfLongDiff": "Dotarłeś do końca!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Prośba o scalenie", "agentManager.import.pastePrUrl": "Wklej URL PR...", "agentManager.import.open": "Otwórz", "agentManager.import.branches": "Branche", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ru.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ru.ts index dcd2d07b895..bef0e8f5e2a 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/ru.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/ru.ts @@ -127,8 +127,10 @@ export const dict = { "agentManager.review.sendToChat": "Отправить в чат", "agentManager.review.collapsedOnly": "{{count}} свернуто", "agentManager.review.collapsedWithLarge": "{{collapsed}} свернуто, {{large}} больших", + "agentManager.review.largeFileCollapsed": "Большой файл (свернут)", + "agentManager.review.endOfLongDiff": "Вы дошли до конца!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "Запрос на слияние", "agentManager.import.pastePrUrl": "Вставьте URL PR...", "agentManager.import.open": "Открыть", "agentManager.import.branches": "Ветки", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/th.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/th.ts index f57327b9f41..5e6db6e91b3 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/th.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/th.ts @@ -128,8 +128,10 @@ export const dict = { "agentManager.review.sendToChat": "ส่งไปยังแชท", "agentManager.review.collapsedOnly": "ยุบ {{count}} รายการ", "agentManager.review.collapsedWithLarge": "ยุบ {{collapsed}} รายการ, ขนาดใหญ่ {{large}} รายการ", + "agentManager.review.largeFileCollapsed": "ไฟล์ขนาดใหญ่ (ย่อไว้)", + "agentManager.review.endOfLongDiff": "คุณมาถึงส่วนท้ายแล้ว!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "คำขอดึง", "agentManager.import.pastePrUrl": "วาง URL ของ PR...", "agentManager.import.open": "เปิด", "agentManager.import.branches": "Branches", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/zh.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/zh.ts index f7dc138c494..3ed6a0bd74f 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/zh.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/zh.ts @@ -126,8 +126,10 @@ export const dict = { "agentManager.review.sendToChat": "发送到聊天", "agentManager.review.collapsedOnly": "{{count}} 个已折叠", "agentManager.review.collapsedWithLarge": "{{collapsed}} 个已折叠,{{large}} 个过大", + "agentManager.review.largeFileCollapsed": "大文件(已折叠)", + "agentManager.review.endOfLongDiff": "您已到达末尾!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "拉取请求", "agentManager.import.pastePrUrl": "粘贴 PR URL...", "agentManager.import.open": "打开", "agentManager.import.branches": "分支", diff --git a/packages/kilo-vscode/webview-ui/agent-manager/i18n/zht.ts b/packages/kilo-vscode/webview-ui/agent-manager/i18n/zht.ts index c36238dac12..279292eac94 100644 --- a/packages/kilo-vscode/webview-ui/agent-manager/i18n/zht.ts +++ b/packages/kilo-vscode/webview-ui/agent-manager/i18n/zht.ts @@ -126,8 +126,10 @@ export const dict = { "agentManager.review.sendToChat": "傳送到聊天", "agentManager.review.collapsedOnly": "{{count}} 個已摺疊", "agentManager.review.collapsedWithLarge": "{{collapsed}} 個已摺疊,{{large}} 個過大", + "agentManager.review.largeFileCollapsed": "大檔案(已摺疊)", + "agentManager.review.endOfLongDiff": "您已到達底部!", - "agentManager.import.pullRequest": "Pull Request", + "agentManager.import.pullRequest": "拉取請求", "agentManager.import.pastePrUrl": "貼上 PR URL...", "agentManager.import.open": "開啟", "agentManager.import.branches": "分支", diff --git a/packages/kilo-vscode/webview-ui/src/App.tsx b/packages/kilo-vscode/webview-ui/src/App.tsx index d466bb1960f..f93c9cdb459 100644 --- a/packages/kilo-vscode/webview-ui/src/App.tsx +++ b/packages/kilo-vscode/webview-ui/src/App.tsx @@ -28,12 +28,21 @@ registerExpandedTaskTool() registerVscodeToolOverrides() import SessionList from "./components/history/SessionList" import CloudSessionList from "./components/history/CloudSessionList" +import { MigrationWizard } from "./components/migration" // legacy-migration import { NotificationsProvider } from "./context/notifications" import type { Message as SDKMessage, Part as SDKPart } from "@kilocode/sdk/v2" import "./styles/chat.css" -type ViewType = "newTask" | "marketplace" | "history" | "cloudHistory" | "profile" | "settings" -const VALID_VIEWS = new Set(["newTask", "marketplace", "history", "cloudHistory", "profile", "settings"]) +type ViewType = "newTask" | "marketplace" | "history" | "cloudHistory" | "profile" | "settings" | "migration" // legacy-migration +const VALID_VIEWS = new Set([ + "newTask", + "marketplace", + "history", + "cloudHistory", + "profile", + "settings", + "migration", +]) // legacy-migration const DummyView: Component<{ title: string }> = (props) => { return ( @@ -240,8 +249,14 @@ const AppContent: Component = () => { /> - setCurrentView("newTask")} /> + setCurrentView("newTask")} onMigrateClick={() => setCurrentView("migration")} /> + {/* legacy-migration */} + {/* legacy-migration start */} + + setCurrentView("newTask")} onComplete={() => setCurrentView("newTask")} /> + + {/* legacy-migration end */} ) diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx index 4242dc89d37..9abcc24eb37 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/AssistantMessage.tsx @@ -3,12 +3,19 @@ * Renders all parts of an assistant message as a flat list — no context grouping. * Unlike the upstream AssistantParts, this renders each read/glob/grep/list tool * individually for maximum verbosity in the VS Code sidebar context. + * + * Permissions and questions with a tool context are rendered inline with their + * tool call rather than in the bottom dock. */ -import { Component, For, Show, createMemo } from "solid-js" +import { Component, For, Show, createMemo, createSignal } from "solid-js" import { Part, PART_MAPPING } from "@kilocode/kilo-ui/message-part" +import { Button } from "@kilocode/kilo-ui/button" import type { AssistantMessage as SDKAssistantMessage, Part as SDKPart, Message as SDKMessage } from "@kilocode/sdk/v2" import { useData } from "@kilocode/kilo-ui/context/data" +import { useSession } from "../../context/session" +import { useLanguage } from "../../context/language" +import { QuestionDock } from "./QuestionDock" const HIDDEN_TOOLS = new Set(["todowrite", "todoread"]) @@ -33,6 +40,8 @@ interface AssistantMessageProps { export const AssistantMessage: Component = (props) => { const data = useData() + const session = useSession() + const language = useLanguage() const parts = createMemo(() => { const stored = data.store.part?.[props.message.id] @@ -40,18 +49,76 @@ export const AssistantMessage: Component = (props) => { return (stored as SDKPart[]).filter(isRenderable) }) + const id = () => session.currentSessionID() + const permissions = () => session.permissions().filter((p) => p.sessionID === id() && p.tool) + const questions = () => session.questions().filter((q) => q.sessionID === id() && q.tool) + + const permissionForPart = (part: SDKPart) => { + if (part.type !== "tool") return undefined + const callID = (part as SDKPart & { callID: string }).callID + return permissions().find((p) => p.tool!.callID === callID && p.tool!.messageID === props.message.id) + } + + // Questions linked to this message (rendered after the last part) + const questionForMessage = () => + questions().find((q) => q.tool!.messageID === props.message.id) + + const [responding, setResponding] = createSignal(false) + + const decide = (permissionId: string, response: "once" | "always" | "reject") => { + if (responding()) return + setResponding(true) + session.respondToPermission(permissionId, response) + setResponding(false) + } + return ( - - {(part) => ( - - - - )} - + <> + + {(part) => { + const perm = () => permissionForPart(part) + return ( + +
+ + + {(p) => ( +
+ 0}> +
+ + {(pattern) => {pattern}} + +
+
+
+ + + +
+

{language.t("ui.permission.sessionHint")}

+
+ )} +
+
+
+ ) + }} +
+ + {(req) => } + + ) } diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx index 2075ee1b796..0f8ea5bf2d8 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/ChatView.tsx @@ -26,7 +26,7 @@ export const ChatView: Component = (props) => { const sessionQuestions = () => session.questions().filter((q) => q.sessionID === id()) const sessionPermissions = () => session.permissions().filter((p) => p.sessionID === id()) - const questionRequest = () => sessionQuestions()[0] + const questionRequest = () => sessionQuestions().find((q) => !q.tool) const permissionRequest = () => sessionPermissions().find((p) => !p.tool) const blocked = () => sessionPermissions().length > 0 || sessionQuestions().length > 0 diff --git a/packages/kilo-vscode/webview-ui/src/components/migration/MigrationWizard.tsx b/packages/kilo-vscode/webview-ui/src/components/migration/MigrationWizard.tsx new file mode 100644 index 00000000000..df8427a1023 --- /dev/null +++ b/packages/kilo-vscode/webview-ui/src/components/migration/MigrationWizard.tsx @@ -0,0 +1,856 @@ +/** + * legacy-migration - Multi-step migration wizard UI component. + * + * Steps: + * 1. Welcome — informs the user about what can / cannot be migrated + * 2. Select — checkboxes for providers, MCP servers, custom modes, default model + * 3. Progress — live progress indicators during migration + * 4. Complete — summary + optional cleanup checkbox + */ + +import { Component, For, Show, Switch, Match, createSignal, onMount, onCleanup, JSX } from "solid-js" +import { useVSCode } from "../../context/vscode" +import { useLanguage } from "../../context/language" +import type { + MigrationProviderInfo, + MigrationMcpServerInfo, + MigrationCustomModeInfo, + MigrationResultItem, + MigrationAutoApprovalSelections, + LegacySettings, + LegacyMigrationDataMessage, + LegacyMigrationProgressMessage, + LegacyMigrationCompleteMessage, +} from "../../types/messages" +import "./migration.css" + +// --------------------------------------------------------------------------- +// KiloLogo — replicates the pattern from MessageList.tsx +// --------------------------------------------------------------------------- + +const KiloLogo = (): JSX.Element => { + const iconsBaseUri = (window as { ICONS_BASE_URI?: string }).ICONS_BASE_URI || "" + const isLight = + document.body.classList.contains("vscode-light") || document.body.classList.contains("vscode-high-contrast-light") + const icon = isLight ? "kilo-light.svg" : "kilo-dark.svg" + return ( + + ) +} + +// --------------------------------------------------------------------------- +// CheckIcon — checkmark SVG for completed steps +// --------------------------------------------------------------------------- + +const CheckIcon = (): JSX.Element => ( + + + +) + +// --------------------------------------------------------------------------- +// Types +// --------------------------------------------------------------------------- + +type Step = "welcome" | "select" | "progress" | "complete" +type StepStatus = "upcoming" | "current" | "done" + +interface ProgressEntry { + item: string + status: "pending" | "migrating" | "success" | "warning" | "error" + message?: string +} + +// --------------------------------------------------------------------------- +// Component +// --------------------------------------------------------------------------- + +export interface MigrationWizardProps { + onBack: () => void + onComplete: () => void +} + +const MigrationWizard: Component = (props) => { + const vscode = useVSCode() + const language = useLanguage() + + const [step, setStep] = createSignal("welcome") + const [providers, setProviders] = createSignal([]) + const [mcpServers, setMcpServers] = createSignal([]) + const [customModes, setCustomModes] = createSignal([]) + const [defaultModel, setDefaultModel] = createSignal<{ provider: string; model: string } | undefined>(undefined) + const [legacySettings, setLegacySettings] = createSignal(undefined) + + // Selections (profile names / server names / mode slugs) + const [selectedProviders, setSelectedProviders] = createSignal>(new Set()) + const [selectedMcpServers, setSelectedMcpServers] = createSignal>(new Set()) + const [selectedModes, setSelectedModes] = createSignal>(new Set()) + const [migrateDefaultModel, setMigrateDefaultModel] = createSignal(true) + const ALL_AP_OFF: MigrationAutoApprovalSelections = { + commandRules: false, + readPermission: false, + writePermission: false, + executePermission: false, + mcpPermission: false, + taskPermission: false, + } + const [autoApprovalSel, setAutoApprovalSel] = createSignal({ ...ALL_AP_OFF }) + const [migrateLanguage, setMigrateLanguage] = createSignal(false) + const [migrateAutocomplete, setMigrateAutocomplete] = createSignal(false) + + // Progress tracking + const [progressEntries, setProgressEntries] = createSignal([]) + const [results, setResults] = createSignal([]) + const [migrationDone, setMigrationDone] = createSignal(false) + + // Cleanup preference on the completion screen + const [clearLegacyData, setClearLegacyData] = createSignal(false) + + // --------------------------------------------------------------------------- + // Message handling + // --------------------------------------------------------------------------- + + onMount(() => { + const handler = (event: MessageEvent) => { + const msg = event.data + if (msg?.type === "legacyMigrationData") { + const data = (msg as LegacyMigrationDataMessage).data + setProviders(data.providers) + setMcpServers(data.mcpServers) + setCustomModes(data.customModes) + setDefaultModel(data.defaultModel) + setLegacySettings(data.settings) + + // Pre-select everything that is supported and has a key + setSelectedProviders( + new Set(data.providers.filter((p) => p.supported && p.hasApiKey).map((p) => p.profileName)), + ) + setSelectedMcpServers(new Set(data.mcpServers.map((s) => s.name))) + setSelectedModes(new Set(data.customModes.map((m) => m.slug))) + setMigrateDefaultModel(Boolean(data.defaultModel)) + + // Pre-select settings migration if data exists + const s = data.settings + if (s) { + setAutoApprovalSel({ + commandRules: + s.autoApprovalEnabled !== undefined || + Boolean(s.allowedCommands?.length) || + Boolean(s.deniedCommands?.length), + readPermission: s.alwaysAllowReadOnly !== undefined || s.alwaysAllowReadOnlyOutsideWorkspace !== undefined, + writePermission: s.alwaysAllowWrite !== undefined, + executePermission: s.alwaysAllowExecute !== undefined, + mcpPermission: s.alwaysAllowMcp !== undefined, + taskPermission: s.alwaysAllowModeSwitch !== undefined || s.alwaysAllowSubtasks !== undefined, + }) + setMigrateLanguage(Boolean(s.language)) + setMigrateAutocomplete(Boolean(s.autocomplete)) + } + } + + if (msg?.type === "legacyMigrationProgress") { + const update = msg as LegacyMigrationProgressMessage + setProgressEntries((prev) => { + const existing = prev.findIndex((e) => e.item === update.item) + const entry: ProgressEntry = { item: update.item, status: update.status, message: update.message } + return existing >= 0 ? prev.map((e, i) => (i === existing ? entry : e)) : [...prev, entry] + }) + } + + if (msg?.type === "legacyMigrationComplete") { + const complete = msg as LegacyMigrationCompleteMessage + setResults(complete.results) + setMigrationDone(true) + setStep("complete") + } + } + + window.addEventListener("message", handler) + // Request data immediately when the wizard mounts + vscode.postMessage({ type: "requestLegacyMigrationData" }) + onCleanup(() => window.removeEventListener("message", handler)) + }) + + // --------------------------------------------------------------------------- + // Actions + // --------------------------------------------------------------------------- + + const handleSkip = () => { + vscode.postMessage({ type: "skipLegacyMigration" }) + props.onBack() + } + + const handleStartMigration = () => { + const allItems: ProgressEntry[] = [ + ...Array.from(selectedProviders()).map((name) => ({ item: name, status: "pending" as const })), + ...Array.from(selectedMcpServers()).map((name) => ({ item: name, status: "pending" as const })), + ...Array.from(selectedModes()).map((slug) => { + const mode = customModes().find((m) => m.slug === slug) + return { item: mode?.name ?? slug, status: "pending" as const } + }), + ...(migrateDefaultModel() && defaultModel() ? [{ item: "Default model", status: "pending" as const }] : []), + ...(autoApprovalSel().commandRules ? [{ item: "Command rules", status: "pending" as const }] : []), + ...(autoApprovalSel().readPermission ? [{ item: "Read permission", status: "pending" as const }] : []), + ...(autoApprovalSel().writePermission ? [{ item: "Write permission", status: "pending" as const }] : []), + ...(autoApprovalSel().executePermission ? [{ item: "Execute permission", status: "pending" as const }] : []), + ...(autoApprovalSel().mcpPermission ? [{ item: "MCP permission", status: "pending" as const }] : []), + ...(autoApprovalSel().taskPermission ? [{ item: "Task permission", status: "pending" as const }] : []), + ...(migrateLanguage() && legacySettings()?.language + ? [{ item: "Language preference", status: "pending" as const }] + : []), + ...(migrateAutocomplete() && legacySettings()?.autocomplete + ? [{ item: "Autocomplete settings", status: "pending" as const }] + : []), + ] + setProgressEntries(allItems) + setStep("progress") + vscode.postMessage({ + type: "startLegacyMigration", + selections: { + providers: Array.from(selectedProviders()), + mcpServers: Array.from(selectedMcpServers()), + customModes: Array.from(selectedModes()), + defaultModel: migrateDefaultModel(), + settings: { + autoApproval: autoApprovalSel(), + language: migrateLanguage(), + autocomplete: migrateAutocomplete(), + }, + }, + }) + } + + const handleDone = () => { + if (clearLegacyData()) { + vscode.postMessage({ type: "clearLegacyData" }) + } + props.onComplete() + } + + // --------------------------------------------------------------------------- + // Selection helpers + // --------------------------------------------------------------------------- + + const toggleProvider = (name: string) => { + setSelectedProviders((prev) => { + const next = new Set(prev) + next.has(name) ? next.delete(name) : next.add(name) + return next + }) + } + + const toggleMcpServer = (name: string) => { + setSelectedMcpServers((prev) => { + const next = new Set(prev) + next.has(name) ? next.delete(name) : next.add(name) + return next + }) + } + + const toggleMode = (slug: string) => { + setSelectedModes((prev) => { + const next = new Set(prev) + next.has(slug) ? next.delete(slug) : next.add(slug) + return next + }) + } + + const anyAutoApprovalSelected = () => Object.values(autoApprovalSel()).some(Boolean) + + const hasAnySelection = () => + selectedProviders().size > 0 || + selectedMcpServers().size > 0 || + selectedModes().size > 0 || + (migrateDefaultModel() && Boolean(defaultModel())) || + anyAutoApprovalSelected() || + (migrateLanguage() && Boolean(legacySettings()?.language)) || + (migrateAutocomplete() && Boolean(legacySettings()?.autocomplete)) + + // --------------------------------------------------------------------------- + // Settings data helpers + // --------------------------------------------------------------------------- + + const hasCommandRulesData = () => { + const s = legacySettings() + return ( + s !== undefined && + (s.autoApprovalEnabled !== undefined || Boolean(s.allowedCommands?.length) || Boolean(s.deniedCommands?.length)) + ) + } + const hasReadPermissionData = () => { + const s = legacySettings() + return ( + s !== undefined && (s.alwaysAllowReadOnly !== undefined || s.alwaysAllowReadOnlyOutsideWorkspace !== undefined) + ) + } + const hasWritePermissionData = () => legacySettings()?.alwaysAllowWrite !== undefined + const hasExecutePermissionData = () => legacySettings()?.alwaysAllowExecute !== undefined + const hasMcpPermissionData = () => legacySettings()?.alwaysAllowMcp !== undefined + const hasTaskPermissionData = () => { + const s = legacySettings() + return s !== undefined && (s.alwaysAllowModeSwitch !== undefined || s.alwaysAllowSubtasks !== undefined) + } + + const hasAnyAutoApprovalData = () => + hasCommandRulesData() || + hasReadPermissionData() || + hasWritePermissionData() || + hasExecutePermissionData() || + hasMcpPermissionData() || + hasTaskPermissionData() + + const hasLanguageData = () => Boolean(legacySettings()?.language) + + const hasAutocompleteData = () => Boolean(legacySettings()?.autocomplete) + + // --------------------------------------------------------------------------- + // Result summary helpers + // --------------------------------------------------------------------------- + + const successCount = () => results().filter((r) => r.status === "success").length + const totalCount = () => results().length + + // --------------------------------------------------------------------------- + // Step indicator helpers + // --------------------------------------------------------------------------- + + // The 3-step indicator maps to the non-welcome steps + const WIZARD_STEPS: Step[] = ["select", "progress", "complete"] + + const stepStatus = (s: Step): StepStatus => { + const idx = WIZARD_STEPS.indexOf(s) + const curr = WIZARD_STEPS.indexOf(step()) + if (curr < 0) return "upcoming" // welcome step — all upcoming + if (curr > idx) return "done" + if (curr === idx) return "current" + return "upcoming" + } + + // --------------------------------------------------------------------------- + // Progress item render helpers + // --------------------------------------------------------------------------- + + const dotColor = (status: ProgressEntry["status"]) => { + switch (status) { + case "success": + return "var(--vscode-testing-iconPassed, #89d185)" + case "warning": + return "var(--vscode-testing-iconQueued, #cca700)" + case "error": + return "var(--vscode-testing-iconFailed, #f14c4c)" + case "migrating": + return "var(--vscode-button-background)" + default: + return "var(--vscode-descriptionForeground)" + } + } + + const statusLabel = (status: ProgressEntry["status"]) => { + switch (status) { + case "success": + return "✓ Done" + case "warning": + return "⚠ Warning" + case "error": + return "✗ Failed" + case "migrating": + return "..." + default: + return "" + } + } + + const statusLabelColor = (status: ProgressEntry["status"]) => { + switch (status) { + case "success": + return "var(--vscode-testing-iconPassed, #89d185)" + case "warning": + return "var(--vscode-testing-iconQueued, #cca700)" + case "error": + return "var(--vscode-testing-iconFailed, #f14c4c)" + default: + return "var(--vscode-descriptionForeground)" + } + } + + // --------------------------------------------------------------------------- + // JSX + // --------------------------------------------------------------------------- + + return ( +
+ {/* Header — only shown on steps 2-4 */} + +
+

{language.t("migration.steps.title")}

+

{language.t("migration.steps.subtitle")}

+ + {/* Step indicator */} +
+ + {(s, i) => ( + <> +
+ + + + + + {i() + 1} + + +
+ + + + + )} +
+
+
+
+ +
+ {/* ---- Step 1: Welcome ---- */} + +
+ +

{language.t("migration.welcome.title")}

+

{language.t("migration.welcome.detected")}

+ +
+
+ {language.t("migration.welcome.sessionsInfo")} +
+ +
+

{language.t("migration.welcome.canMigrate")}

+
    + 0}> +
  • + {language.t("migration.select.providers")} ({providers().filter((p) => p.supported).length}) +
  • +
    + 0}> +
  • + {language.t("migration.select.mcpServers")} ({mcpServers().length}) +
  • +
    + 0}> +
  • + {language.t("migration.select.customModes")} ({customModes().length}) +
  • +
    + +
  • {language.t("migration.select.defaultModel")}
  • +
    + +
  • {language.t("migration.select.autoApproval")}
  • +
    + +
  • {language.t("migration.select.language")}
  • +
    + +
  • {language.t("migration.select.autocomplete")}
  • +
    +
+
+
+
+ + +
+ + {/* ---- Step 2: Select ---- */} + +
+ {/* Provider API Keys */} + 0}> +
+

{language.t("migration.select.providers")}

+ + {(provider) => ( + + )} + +
+
+ + {/* MCP Servers */} + 0}> +
+

{language.t("migration.select.mcpServers")}

+ + {(server) => ( + + )} + +
+
+ + {/* Custom Modes */} + 0}> +
+

{language.t("migration.select.customModes")}

+ + {(mode) => ( + + )} + +
+
+ + {/* Default Model */} + +
+

{language.t("migration.select.defaultModel")}

+ +
+
+ + {/* Settings (auto-approval, language, autocomplete) */} + +
+

{language.t("migration.select.settings")}

+ + {/* Auto-Approval — one row per permission group */} + +

{language.t("migration.select.autoApproval")}

+ + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+
+ + +

{language.t("migration.select.nothingToMigrate")}

+
+
+ + +
+ + {/* ---- Step 3: Progress ---- */} + +
+
+

{language.t("migration.progress.title")}

+
+ + {(entry) => ( +
+ + {entry.item} + + {entry.message} + + + + {statusLabel(entry.status)} + + +
+ )} +
+
+
+
+ + +
+ + {/* ---- Step 4: Complete ---- */} + +
+
+ + {language.t("migration.complete.summary", { + success: String(successCount()), + total: String(totalCount()), + })} + +
+ + +
+ + +
+
+
+ ) +} + +export default MigrationWizard diff --git a/packages/kilo-vscode/webview-ui/src/components/migration/index.ts b/packages/kilo-vscode/webview-ui/src/components/migration/index.ts new file mode 100644 index 00000000000..824db6d8440 --- /dev/null +++ b/packages/kilo-vscode/webview-ui/src/components/migration/index.ts @@ -0,0 +1,5 @@ +/** + * legacy-migration - Barrel export for the migration wizard webview components. + * Delete this entire directory when dropping legacy migration support. + */ +export { default as MigrationWizard } from "./MigrationWizard" diff --git a/packages/kilo-vscode/webview-ui/src/components/migration/migration.css b/packages/kilo-vscode/webview-ui/src/components/migration/migration.css new file mode 100644 index 00000000000..43869d7f055 --- /dev/null +++ b/packages/kilo-vscode/webview-ui/src/components/migration/migration.css @@ -0,0 +1,443 @@ +/* legacy-migration - Scoped styles for the migration wizard. */ + +.migration-wizard { + display: flex; + flex-direction: column; + height: 100%; + overflow: hidden; + font-size: 13px; + color: var(--vscode-foreground); +} + +/* Header */ +.migration-wizard__header { + padding: 16px 20px 14px; + border-bottom: 1px solid var(--vscode-panel-border, var(--border-weak-base)); + flex-shrink: 0; +} + +.migration-wizard__title { + font-size: 16px; + font-weight: 600; + margin: 0 0 4px; +} + +.migration-wizard__header-subtitle { + font-size: 11px; + color: var(--vscode-descriptionForeground); + margin: 0 0 12px; + line-height: 1.4; +} + +/* Body */ +.migration-wizard__body { + flex: 1; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 16px 20px; + gap: 12px; +} + +/* Welcome screen — centered hero layout */ +.migration-wizard__welcome { + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + text-align: center; + overflow-y: auto; + padding: 28px 8px 8px; + gap: 0; + min-height: 0; +} + +.migration-wizard__welcome-logo { + width: 52px; + height: 52px; + margin-bottom: 16px; + flex-shrink: 0; +} + +.migration-wizard__welcome-logo img { + width: 100%; + height: 100%; + object-fit: contain; +} + +.migration-wizard__welcome-title { + font-size: 18px; + font-weight: 600; + margin: 0 0 8px; + color: var(--vscode-foreground); +} + +.migration-wizard__welcome-subtitle { + margin: 0 0 20px; + text-align: center; + color: var(--vscode-descriptionForeground); + font-size: 12px; +} + +.migration-wizard__welcome-cards { + display: flex; + flex-direction: column; + gap: 10px; + width: 100%; + text-align: left; +} + +/* Step indicator */ +.migration-wizard__steps { + display: flex; + align-items: center; + gap: 0; + flex-shrink: 0; +} + +.migration-wizard__step { + display: flex; + align-items: center; + justify-content: center; + width: 28px; + height: 28px; + border-radius: 50%; + font-size: 12px; + font-weight: 600; + flex-shrink: 0; + transition: all 0.2s ease; + user-select: none; +} + +/* Connector line rendered as a sibling element in the JSX */ +.migration-wizard__step-connector { + width: 28px; + height: 2px; + background: var(--vscode-panel-border); + flex-shrink: 0; + margin: 0 2px; + transition: background 0.2s ease; +} + +.migration-wizard__step-connector--done { + background: var(--vscode-testing-iconPassed, #89d185); +} + +.migration-wizard__step--upcoming { + background: var(--vscode-input-background); + border: 1px solid var(--vscode-panel-border); + color: var(--vscode-descriptionForeground); +} + +.migration-wizard__step--current { + background: var(--vscode-button-background); + color: var(--vscode-button-foreground); + box-shadow: + 0 0 0 2px color-mix(in srgb, var(--vscode-button-background) 40%, transparent), + 0 0 0 4px var(--vscode-editor-background, var(--vscode-sideBar-background)); +} + +.migration-wizard__step--done { + background: var(--vscode-testing-iconPassed, #89d185); + color: #fff; +} + +/* Scrollable content area */ +.migration-wizard__content { + flex: 1; + overflow-y: auto; + display: flex; + flex-direction: column; + gap: 12px; + min-height: 0; +} + +/* Lead paragraph */ +.migration-wizard__lead { + margin: 0 0 8px; + color: var(--vscode-descriptionForeground); + font-size: 12px; + line-height: 1.5; +} + +/* Info cards */ +.migration-wizard__info-card { + background: var(--vscode-editor-background); + border: 1px solid var(--vscode-panel-border); + border-radius: 4px; + padding: 12px; + font-size: 12px; + line-height: 1.5; + color: var(--vscode-descriptionForeground); +} + +.migration-wizard__info-card--warning { + border-color: var(--vscode-inputValidation-warningBorder, #cca700); + background: var(--vscode-inputValidation-warningBackground, rgba(204, 167, 0, 0.1)); + color: var(--vscode-foreground); +} + +.migration-wizard__info-card--success { + border-color: var(--vscode-testing-iconPassed, #89d185); + background: rgba(137, 209, 133, 0.08); + color: var(--vscode-foreground); +} + +.migration-wizard__list { + margin: 8px 0 0 0; + padding-left: 20px; +} + +.migration-wizard__list li { + margin-bottom: 4px; +} + +/* Section groups */ +.migration-wizard__section { + display: flex; + flex-direction: column; + gap: 4px; +} + +.migration-wizard__section-title { + font-size: 11px; + font-weight: 600; + color: var(--vscode-descriptionForeground); + margin: 0 0 4px 0; + padding-bottom: 6px; + border-bottom: 1px solid var(--vscode-panel-border); + text-transform: uppercase; + letter-spacing: 0.06em; +} + +.migration-wizard__section-subtitle { + font-size: 11px; + font-weight: 600; + color: var(--vscode-descriptionForeground); + margin: 8px 0 2px 0; + text-transform: uppercase; + letter-spacing: 0.04em; + opacity: 0.8; +} + +/* Checkbox items */ +.migration-wizard__item { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 6px 4px; + cursor: pointer; + border-radius: 3px; +} + +.migration-wizard__item:hover { + background: var(--vscode-list-hoverBackground); +} + +.migration-wizard__item--disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.migration-wizard__item input[type="checkbox"] { + margin-top: 2px; + flex-shrink: 0; +} + +.migration-wizard__item-info { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; +} + +.migration-wizard__item-name { + font-size: 12px; + color: var(--vscode-foreground); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.migration-wizard__item-meta { + font-size: 11px; + color: var(--vscode-descriptionForeground); + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.migration-wizard__item-tag { + display: inline-block; + font-size: 10px; + padding: 1px 5px; + border-radius: 10px; + margin-top: 2px; +} + +.migration-wizard__item-tag--warn { + background: rgba(204, 167, 0, 0.15); + color: var(--vscode-testing-iconQueued, #cca700); + border: 1px solid var(--vscode-inputValidation-warningBorder, #cca700); +} + +.migration-wizard__empty { + margin: 0; + color: var(--vscode-descriptionForeground); + font-style: italic; +} + +/* Approval settings info note */ +.migration-wizard__note { + display: flex; + align-items: flex-start; + gap: 6px; + padding: 0 2px; + margin-top: 4px; +} + +.migration-wizard__note-icon { + flex-shrink: 0; + margin-top: 1px; + color: var(--vscode-descriptionForeground); +} + +.migration-wizard__note-text { + margin: 0; + font-size: 11px; + color: var(--vscode-descriptionForeground); + line-height: 1.4; +} + +/* Progress card wrapper */ +.migration-wizard__progress-card { + background: var(--vscode-editor-background); + border: 1px solid var(--vscode-panel-border); + border-radius: 4px; + padding: 12px; +} + +/* Progress list */ +.migration-wizard__progress-list { + display: flex; + flex-direction: column; + gap: 6px; +} + +.migration-wizard__progress-item { + display: flex; + align-items: center; + gap: 8px; + font-size: 12px; +} + +.migration-wizard__progress-dot { + width: 8px; + height: 8px; + border-radius: 50%; + flex-shrink: 0; +} + +.migration-wizard__progress-name { + color: var(--vscode-foreground); + flex: 1; + min-width: 0; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.migration-wizard__progress-msg { + color: var(--vscode-descriptionForeground); + font-size: 11px; + flex-shrink: 0; +} + +.migration-wizard__progress-label { + font-size: 11px; + flex-shrink: 0; + margin-left: auto; +} + +/* Cleanup checkbox on completion screen */ +.migration-wizard__cleanup { + display: flex; + align-items: flex-start; + gap: 8px; + padding: 12px; + background: var(--vscode-editor-background); + border: 1px solid var(--vscode-panel-border); + border-radius: 4px; + cursor: pointer; + transition: background 0.1s; +} + +.migration-wizard__cleanup:hover { + background: var(--vscode-list-hoverBackground); +} + +.migration-wizard__cleanup input[type="checkbox"] { + margin-top: 2px; + flex-shrink: 0; +} + +.migration-wizard__cleanup-label { + display: block; + font-size: 12px; + color: var(--vscode-foreground); + font-weight: 500; +} + +.migration-wizard__cleanup-desc { + display: block; + font-size: 11px; + color: var(--vscode-descriptionForeground); + margin-top: 2px; + line-height: 1.4; +} + +/* Footer with action buttons */ +.migration-wizard__footer { + display: flex; + justify-content: flex-end; + gap: 8px; + flex-shrink: 0; + padding-top: 8px; + border-top: 1px solid var(--vscode-panel-border); +} + +/* Buttons */ +.migration-wizard__btn { + padding: 6px 14px; + font-size: 12px; + border-radius: 4px; + border: none; + cursor: pointer; + font-family: var(--vscode-font-family); + font-weight: 500; + transition: opacity 0.1s; +} + +.migration-wizard__btn:disabled { + opacity: 0.5; + cursor: not-allowed; +} + +.migration-wizard__btn--primary { + background: var(--vscode-button-background); + color: var(--vscode-button-foreground); +} + +.migration-wizard__btn--primary:not(:disabled):hover { + background: var(--vscode-button-hoverBackground); +} + +.migration-wizard__btn--ghost { + background: transparent; + color: var(--vscode-descriptionForeground); +} + +.migration-wizard__btn--ghost:hover { + background: var(--vscode-list-hoverBackground); + color: var(--vscode-foreground); +} diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/AboutKiloCodeTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/AboutKiloCodeTab.tsx index 35d004c5e58..cbf098b2a35 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/AboutKiloCodeTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/AboutKiloCodeTab.tsx @@ -7,6 +7,7 @@ export interface AboutKiloCodeTabProps { port: number | null connectionState: ConnectionState extensionVersion?: string + onMigrateClick?: () => void // legacy-migration } const AboutKiloCodeTab: Component = (props) => { @@ -157,8 +158,39 @@ const AboutKiloCodeTab: Component = (props) => { - {/* Reset Settings */} + {/* legacy-migration start */}
+

{language.t("settings.aboutKiloCode.legacyMigration.title")}

+

+ {language.t("settings.aboutKiloCode.legacyMigration.description")} +

+ +
+ {/* legacy-migration end */} + + {/* Reset Settings */} +

{language.t("settings.aboutKiloCode.resetSettings.title")}

void + onMigrateClick?: () => void // legacy-migration } const Settings: Component = (props) => { @@ -167,6 +168,7 @@ const Settings: Component = (props) => { port={server.serverInfo()?.port ?? null} connectionState={server.connectionState()} extensionVersion={server.extensionVersion()} + onMigrateClick={props.onMigrateClick} /> diff --git a/packages/kilo-vscode/webview-ui/src/context/language.tsx b/packages/kilo-vscode/webview-ui/src/context/language.tsx index 6eef841021c..7e25c50fea4 100644 --- a/packages/kilo-vscode/webview-ui/src/context/language.tsx +++ b/packages/kilo-vscode/webview-ui/src/context/language.tsx @@ -193,7 +193,7 @@ interface LanguageContextValue { t: (key: string, params?: UiI18nParams) => string } -const LanguageContext = createContext() +export const LanguageContext = createContext() export function useLanguage() { const ctx = useContext(LanguageContext) diff --git a/packages/kilo-vscode/webview-ui/src/context/session.tsx b/packages/kilo-vscode/webview-ui/src/context/session.tsx index 82962c4a9eb..27f9cc6646b 100644 --- a/packages/kilo-vscode/webview-ui/src/context/session.tsx +++ b/packages/kilo-vscode/webview-ui/src/context/session.tsx @@ -138,7 +138,7 @@ interface SessionContextValue { selectCloudSession: (cloudSessionId: string) => void } -const SessionContext = createContext() +export const SessionContext = createContext() export const SessionProvider: ParentComponent = (props) => { const vscode = useVSCode() diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ar.ts b/packages/kilo-vscode/webview-ui/src/i18n/ar.ts index 18e806bb202..6144599928f 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ar.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ar.ts @@ -946,4 +946,52 @@ export const dict = { "question.summary": "{{n}} من {{total}} أسئلة", "common.review": "مراجعة", + + // legacy-migration start + "settings.legacyMigration.link": "الترحيل من الإصدار القديم", + "settings.aboutKiloCode.legacyMigration.title": "ترحيل الإصدار القديم", + "settings.aboutKiloCode.legacyMigration.description": + "ترحيل الإعدادات من تثبيت سابق لـ Kilo Code، بما في ذلك مفاتيح API لمقدمي الخدمة والنموذج الافتراضي.", + "migration.welcome.title": "مرحبًا بك في Kilo Code الجديد", + "migration.welcome.detected": "لقد اكتشفنا إعدادات من تثبيت سابق لـ Kilo Code.", + "migration.welcome.sessionsInfo": "لا يمكن ترحيل جلسات الدردشة والسجل — الإصدار الجديد يستخدم بنية مختلفة.", + "migration.welcome.canMigrate": "يمكن ترحيل الإعدادات التالية إلى الإصدار الجديد:", + "migration.welcome.start": "بدء الترحيل", + "migration.welcome.skip": "تخطي الترحيل", + "migration.steps.title": "ترحيل إعداداتك", + "migration.steps.subtitle": "لقد وجدنا إعدادات من تثبيت Kilo Code السابق. اختر ما تريد نقله.", + "migration.select.providers": "مفاتيح API لمقدمي الخدمة", + "migration.select.mcpServers": "خوادم MCP", + "migration.select.customModes": "الأوضاع المخصصة / الوكلاء", + "migration.select.defaultModel": "النموذج الافتراضي", + "migration.select.unsupported": "غير مدعوم في الإصدار الجديد", + "migration.select.nothingToMigrate": "لم يتم العثور على أي شيء لترحيله في الإعدادات القديمة.", + "migration.select.settings": "الإعدادات", + "migration.select.autoApproval": "الموافقة التلقائية", + "migration.select.autoApproval.commandRules": "قواعد الأوامر", + "migration.select.autoApproval.commandRulesDesc": "مفتاح التبديل الرئيسي وقوائم الأوامر المسموح بها/المرفوضة", + "migration.select.autoApproval.readPermission": "صلاحية القراءة", + "migration.select.autoApproval.readPermissionDesc": "الوصول لقراءة الملفات داخل وخارج مساحة العمل", + "migration.select.autoApproval.writePermission": "صلاحية الكتابة", + "migration.select.autoApproval.writePermissionDesc": "الوصول لكتابة وتعديل الملفات", + "migration.select.autoApproval.executePermission": "صلاحية التنفيذ", + "migration.select.autoApproval.executePermissionDesc": "تنفيذ أوامر الوحدة الطرفية", + "migration.select.autoApproval.mcpPermission": "صلاحية MCP", + "migration.select.autoApproval.mcpPermissionDesc": "استخدام أدوات MCP", + "migration.select.autoApproval.taskPermission": "صلاحية المهام", + "migration.select.autoApproval.taskPermissionDesc": "تبديل الوضع وإنشاء المهام الفرعية", + "migration.select.language": "لغة واجهة المستخدم", + "migration.select.languageDesc": "سيتم تطبيق لغتك المفضلة على الإضافة الجديدة", + "migration.select.autocomplete": "إعدادات الإكمال التلقائي", + "migration.select.autocompleteDesc": "تفضيلات التشغيل التلقائي، واختصارات لوحة المفاتيح، والإكمال التلقائي للدردشة", + "migration.select.continue": "متابعة", + "migration.select.back": "رجوع", + "migration.progress.title": "جاري ترحيل إعداداتك…", + "migration.progress.done": "متابعة", + "migration.complete.summary": "تم ترحيل {{success}} من {{total}} عناصر بنجاح.", + "migration.complete.cleanup": "إزالة بيانات الإعدادات القديمة", + "migration.complete.cleanupDescription": + "هذا يزيل الإعدادات القديمة من مساحة تخزين VS Code. لن تتمكن من إعادة تشغيل هذا الترحيل.", + "migration.complete.done": "تم", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/br.ts b/packages/kilo-vscode/webview-ui/src/i18n/br.ts index 73b638ea0a9..e7dfc02f69f 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/br.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/br.ts @@ -960,4 +960,54 @@ export const dict = { "question.summary": "{{n}} de {{total}} perguntas", "common.review": "Revisar", + + // legacy-migration start + "settings.legacyMigration.link": "Migrar da Versão Legada", + "settings.aboutKiloCode.legacyMigration.title": "Migração Legada", + "settings.aboutKiloCode.legacyMigration.description": + "Migre as configurações de uma instalação anterior do Kilo Code, incluindo chaves de API de provedor e modelo padrão.", + "migration.welcome.title": "Bem-vindo ao Novo Kilo Code", + "migration.welcome.detected": "Detectamos configurações de uma instalação anterior do Kilo Code.", + "migration.welcome.sessionsInfo": + "Sessões de chat e histórico não podem ser migrados — a nova versão usa uma arquitetura diferente.", + "migration.welcome.canMigrate": "As seguintes configurações podem ser migradas para a nova versão:", + "migration.welcome.start": "Iniciar Migração", + "migration.welcome.skip": "Pular Migração", + "migration.steps.title": "Migre suas configurações", + "migration.steps.subtitle": + "Encontramos configurações da sua instalação anterior do Kilo Code. Escolha o que trazer.", + "migration.select.providers": "Chaves de API de Provedor", + "migration.select.mcpServers": "Servidores MCP", + "migration.select.customModes": "Modos Personalizados / Agentes", + "migration.select.defaultModel": "Modelo Padrão", + "migration.select.unsupported": "Não suportado na nova versão", + "migration.select.nothingToMigrate": "Nada para migrar foi encontrado nas configurações legadas.", + "migration.select.settings": "Configurações", + "migration.select.autoApproval": "Aprovação Automática", + "migration.select.autoApproval.commandRules": "Regras de Comando", + "migration.select.autoApproval.commandRulesDesc": "Alternador principal e listas de comandos permitidos/negados", + "migration.select.autoApproval.readPermission": "Permissão de Leitura", + "migration.select.autoApproval.readPermissionDesc": "Acesso de leitura de arquivos dentro e fora do workspace", + "migration.select.autoApproval.writePermission": "Permissão de Escrita", + "migration.select.autoApproval.writePermissionDesc": "Acesso de escrita e edição de arquivos", + "migration.select.autoApproval.executePermission": "Permissão de Execução", + "migration.select.autoApproval.executePermissionDesc": "Execução de comandos de terminal", + "migration.select.autoApproval.mcpPermission": "Permissão MCP", + "migration.select.autoApproval.mcpPermissionDesc": "Uso de ferramentas MCP", + "migration.select.autoApproval.taskPermission": "Permissão de Tarefa", + "migration.select.autoApproval.taskPermissionDesc": "Troca de modo e criação de subtarefas", + "migration.select.language": "Idioma da Interface", + "migration.select.languageDesc": "Sua preferência de idioma será aplicada à nova extensão", + "migration.select.autocomplete": "Configurações de Autocomplete", + "migration.select.autocompleteDesc": "Preferências de gatilho automático, atalhos de teclado e autocomplete do chat", + "migration.select.continue": "Continuar", + "migration.select.back": "Voltar", + "migration.progress.title": "Migrando suas configurações…", + "migration.progress.done": "Continuar", + "migration.complete.summary": "{{success}} de {{total}} itens migrados com sucesso.", + "migration.complete.cleanup": "Remover dados de configurações legadas", + "migration.complete.cleanupDescription": + "Isso remove as configurações antigas do armazenamento do VS Code. Você não poderá executar esta migração novamente.", + "migration.complete.done": "Concluído", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/bs.ts b/packages/kilo-vscode/webview-ui/src/i18n/bs.ts index 390ee8e840b..3892080f9a5 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/bs.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/bs.ts @@ -982,4 +982,55 @@ export const dict = { "question.summary": "{{n}} od {{total}} pitanja", "common.review": "Pregled", + + // legacy-migration start + "settings.legacyMigration.link": "Migriraj sa prethodne verzije", + "settings.aboutKiloCode.legacyMigration.title": "Migracija sa prethodne verzije", + "settings.aboutKiloCode.legacyMigration.description": + "Migrirajte postavke iz prethodne instalacije Kilo Code, uključujući API ključeve provajdera i podrazumijevani model.", + "migration.welcome.title": "Dobrodošli u novi Kilo Code", + "migration.welcome.detected": "Otkrili smo postavke iz prethodne instalacije Kilo Code.", + "migration.welcome.sessionsInfo": + "Sesije razgovora i historija se ne mogu migrirati — nova verzija koristi drugačiju arhitekturu.", + "migration.welcome.canMigrate": "Sljedeće postavke se mogu migrirati na novu verziju:", + "migration.welcome.start": "Započni migraciju", + "migration.welcome.skip": "Preskoči migraciju", + "migration.steps.title": "Migrirajte svoje postavke", + "migration.steps.subtitle": + "Pronašli smo postavke iz vaše prethodne instalacije Kilo Code. Odaberite šta želite prenijeti.", + "migration.select.providers": "API ključevi provajdera", + "migration.select.mcpServers": "MCP serveri", + "migration.select.customModes": "Prilagođeni režimi / Agenti", + "migration.select.defaultModel": "Podrazumijevani model", + "migration.select.unsupported": "Nije podržano u novoj verziji", + "migration.select.nothingToMigrate": "U starim postavkama nije pronađeno ništa za migraciju.", + "migration.select.settings": "Postavke", + "migration.select.autoApproval": "Automatsko odobravanje", + "migration.select.autoApproval.commandRules": "Pravila za komande", + "migration.select.autoApproval.commandRulesDesc": "Glavni prekidač i liste dozvoljenih/odbijenih komandi", + "migration.select.autoApproval.readPermission": "Dozvola za čitanje", + "migration.select.autoApproval.readPermissionDesc": "Pristup čitanju datoteka unutar i izvan radnog prostora", + "migration.select.autoApproval.writePermission": "Dozvola za pisanje", + "migration.select.autoApproval.writePermissionDesc": "Pristup za pisanje i uređivanje datoteka", + "migration.select.autoApproval.executePermission": "Dozvola za izvršavanje", + "migration.select.autoApproval.executePermissionDesc": "Izvršavanje komandi u terminalu", + "migration.select.autoApproval.mcpPermission": "MCP dozvola", + "migration.select.autoApproval.mcpPermissionDesc": "Korištenje MCP alata", + "migration.select.autoApproval.taskPermission": "Dozvola za zadatke", + "migration.select.autoApproval.taskPermissionDesc": "Mijenjanje režima i kreiranje podzadataka", + "migration.select.language": "Jezik korisničkog interfejsa", + "migration.select.languageDesc": "Vaše željene postavke jezika će biti primijenjene na novu ekstenziju", + "migration.select.autocomplete": "Postavke automatskog dovršavanja", + "migration.select.autocompleteDesc": + "Postavke automatskog pokretanja, prečica na tastaturi i automatskog dovršavanja u chatu", + "migration.select.continue": "Nastavi", + "migration.select.back": "Nazad", + "migration.progress.title": "Migriranje vaših postavki…", + "migration.progress.done": "Nastavi", + "migration.complete.summary": "Uspješno migrirano {{success}} od {{total}} stavki.", + "migration.complete.cleanup": "Ukloni stare podatke postavki", + "migration.complete.cleanupDescription": + "Ovo uklanja stare postavke iz VS Code pohrane. Nećete moći ponovo pokrenuti ovu migraciju.", + "migration.complete.done": "Završeno", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/da.ts b/packages/kilo-vscode/webview-ui/src/i18n/da.ts index 91547e71095..1cd4cd9fabe 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/da.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/da.ts @@ -955,4 +955,54 @@ export const dict = { "question.summary": "{{n}} af {{total}} spørgsmål", "common.review": "Gennemgå", + + // legacy-migration start + "settings.legacyMigration.link": "Migrer fra legacy-version", + "settings.aboutKiloCode.legacyMigration.title": "Legacy-migrering", + "settings.aboutKiloCode.legacyMigration.description": + "Migrer indstillinger fra en tidligere installation af Kilo Code, herunder udbyder API-nøgler og standardmodel.", + "migration.welcome.title": "Velkommen til det nye Kilo Code", + "migration.welcome.detected": "Vi har fundet indstillinger fra en tidligere installation af Kilo Code.", + "migration.welcome.sessionsInfo": + "Chatsessioner og historik kan ikke migreres — den nye version bruger en anden arkitektur.", + "migration.welcome.canMigrate": "Følgende indstillinger kan migreres til den nye version:", + "migration.welcome.start": "Start migrering", + "migration.welcome.skip": "Spring migrering over", + "migration.steps.title": "Migrer dine indstillinger", + "migration.steps.subtitle": + "Vi har fundet indstillinger fra din tidligere Kilo Code-installation. Vælg, hvad der skal overføres.", + "migration.select.providers": "Udbyder API-nøgler", + "migration.select.mcpServers": "MCP-servere", + "migration.select.customModes": "Brugerdefinerede tilstande / Agenter", + "migration.select.defaultModel": "Standardmodel", + "migration.select.unsupported": "Understøttes ikke i den nye version", + "migration.select.nothingToMigrate": "Der blev ikke fundet noget at migrere i legacy-indstillingerne.", + "migration.select.settings": "Indstillinger", + "migration.select.autoApproval": "Automatisk godkendelse", + "migration.select.autoApproval.commandRules": "Kommandoregler", + "migration.select.autoApproval.commandRulesDesc": "Hovedafbryder og lister over tilladte/afviste kommandoer", + "migration.select.autoApproval.readPermission": "Læsetilladelse", + "migration.select.autoApproval.readPermissionDesc": "Fillæseadgang inden for og uden for arbejdsområdet", + "migration.select.autoApproval.writePermission": "Skrivetilladelse", + "migration.select.autoApproval.writePermissionDesc": "Filskrive- og redigeringsadgang", + "migration.select.autoApproval.executePermission": "Udførelsestilladelse", + "migration.select.autoApproval.executePermissionDesc": "Udførelse af terminalkommandoer", + "migration.select.autoApproval.mcpPermission": "MCP-tilladelse", + "migration.select.autoApproval.mcpPermissionDesc": "Brug af MCP-værktøjer", + "migration.select.autoApproval.taskPermission": "Opgavetilladelse", + "migration.select.autoApproval.taskPermissionDesc": "Skift af tilstand og oprettelse af underopgaver", + "migration.select.language": "UI-sprog", + "migration.select.languageDesc": "Din sprogpræference vil blive anvendt på den nye udvidelse", + "migration.select.autocomplete": "Indstillinger for autofuldførelse", + "migration.select.autocompleteDesc": "Præferencer for automatisk udløsning, genvejstaster og chat-autofuldførelse", + "migration.select.continue": "Fortsæt", + "migration.select.back": "Tilbage", + "migration.progress.title": "Migrerer dine indstillinger…", + "migration.progress.done": "Fortsæt", + "migration.complete.summary": "{{success}} af {{total}} elementer blev migreret med succes.", + "migration.complete.cleanup": "Fjern legacy-indstillingsdata", + "migration.complete.cleanupDescription": + "Dette fjerner de gamle indstillinger fra VS Code-lageret. Du vil ikke kunne køre denne migrering igen.", + "migration.complete.done": "Færdig", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/de.ts b/packages/kilo-vscode/webview-ui/src/i18n/de.ts index 4559136d14a..e7f255f8609 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/de.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/de.ts @@ -968,4 +968,55 @@ export const dict = { "question.summary": "{{n}} von {{total}} Fragen", "common.review": "Überprüfen", + + // legacy-migration start + "settings.legacyMigration.link": "Von der Legacy-Version migrieren", + "settings.aboutKiloCode.legacyMigration.title": "Legacy-Migration", + "settings.aboutKiloCode.legacyMigration.description": + "Migrieren Sie Einstellungen von einer früheren Installation von Kilo Code, einschließlich Anbieter-API-Schlüsseln und dem Standardmodell.", + "migration.welcome.title": "Willkommen beim neuen Kilo Code", + "migration.welcome.detected": "Wir haben Einstellungen aus einer früheren Installation von Kilo Code erkannt.", + "migration.welcome.sessionsInfo": + "Chat-Sitzungen und Verlauf können nicht migriert werden — die neue Version verwendet eine andere Architektur.", + "migration.welcome.canMigrate": "Die folgenden Einstellungen können in die neue Version migriert werden:", + "migration.welcome.start": "Migration starten", + "migration.welcome.skip": "Migration überspringen", + "migration.steps.title": "Ihre Einstellungen migrieren", + "migration.steps.subtitle": + "Wir haben Einstellungen aus Ihrer vorherigen Kilo Code-Installation gefunden. Wählen Sie aus, was übernommen werden soll.", + "migration.select.providers": "Anbieter-API-Schlüssel", + "migration.select.mcpServers": "MCP-Server", + "migration.select.customModes": "Benutzerdefinierte Modi / Agenten", + "migration.select.defaultModel": "Standardmodell", + "migration.select.unsupported": "Wird in der neuen Version nicht unterstützt", + "migration.select.nothingToMigrate": "In den Legacy-Einstellungen wurde nichts gefunden, was migriert werden könnte.", + "migration.select.settings": "Einstellungen", + "migration.select.autoApproval": "Automatische Genehmigung", + "migration.select.autoApproval.commandRules": "Befehlsregeln", + "migration.select.autoApproval.commandRulesDesc": "Hauptschalter und Listen für erlaubte/verweigerte Befehle", + "migration.select.autoApproval.readPermission": "Leseberechtigung", + "migration.select.autoApproval.readPermissionDesc": "Dateilesezugriff innerhalb und außerhalb des Arbeitsbereichs", + "migration.select.autoApproval.writePermission": "Schreibberechtigung", + "migration.select.autoApproval.writePermissionDesc": "Dateischreib- und Bearbeitungszugriff", + "migration.select.autoApproval.executePermission": "Ausführungsberechtigung", + "migration.select.autoApproval.executePermissionDesc": "Ausführung von Terminalbefehlen", + "migration.select.autoApproval.mcpPermission": "MCP-Berechtigung", + "migration.select.autoApproval.mcpPermissionDesc": "Nutzung von MCP-Tools", + "migration.select.autoApproval.taskPermission": "Aufgabenberechtigung", + "migration.select.autoApproval.taskPermissionDesc": "Wechsel des Modus und Erstellung von Teilaufgaben", + "migration.select.language": "UI-Sprache", + "migration.select.languageDesc": "Ihre Spracheinstellung wird auf die neue Erweiterung angewendet", + "migration.select.autocomplete": "Einstellungen für Autovervollständigung", + "migration.select.autocompleteDesc": + "Einstellungen für automatische Auslösung, Tastenkombinationen und Chat-Autovervollständigung", + "migration.select.continue": "Weiter", + "migration.select.back": "Zurück", + "migration.progress.title": "Ihre Einstellungen werden migriert…", + "migration.progress.done": "Weiter", + "migration.complete.summary": "{{success}} von {{total}} Elementen erfolgreich migriert.", + "migration.complete.cleanup": "Legacy-Einstellungsdaten entfernen", + "migration.complete.cleanupDescription": + "Dadurch werden die alten Einstellungen aus dem VS Code-Speicher entfernt. Sie können diese Migration danach nicht erneut ausführen.", + "migration.complete.done": "Fertig", + // legacy-migration end } satisfies Partial> diff --git a/packages/kilo-vscode/webview-ui/src/i18n/en.ts b/packages/kilo-vscode/webview-ui/src/i18n/en.ts index 93f16b48bde..fc28988bb68 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/en.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/en.ts @@ -1001,4 +1001,53 @@ export const dict = { "question.summary": "{{n}} of {{total}} questions", "common.review": "Review", + + // legacy-migration start + "settings.legacyMigration.link": "Migrate from Legacy Version", + "settings.aboutKiloCode.legacyMigration.title": "Legacy Migration", + "settings.aboutKiloCode.legacyMigration.description": + "Migrate settings from a previous installation of Kilo Code, including provider API keys and default model.", + "migration.welcome.title": "Welcome to the New Kilo Code", + "migration.welcome.detected": "We detected settings from a previous installation of Kilo Code.", + "migration.welcome.sessionsInfo": + "Chat sessions and history cannot be migrated — the new version uses a different architecture.", + "migration.welcome.canMigrate": "The following settings can be migrated to the new version:", + "migration.welcome.start": "Start Migration", + "migration.welcome.skip": "Skip Migration", + "migration.steps.title": "Migrate your settings", + "migration.steps.subtitle": "We found settings from your previous Kilo Code installation. Choose what to bring over.", + "migration.select.providers": "Provider API Keys", + "migration.select.mcpServers": "MCP Servers", + "migration.select.customModes": "Custom Modes / Agents", + "migration.select.defaultModel": "Default Model", + "migration.select.unsupported": "Not supported in new version", + "migration.select.nothingToMigrate": "Nothing to migrate was found in the legacy settings.", + "migration.select.settings": "Settings", + "migration.select.autoApproval": "Auto-Approval", + "migration.select.autoApproval.commandRules": "Command Rules", + "migration.select.autoApproval.commandRulesDesc": "Master toggle and allowed/denied command lists", + "migration.select.autoApproval.readPermission": "Read Permission", + "migration.select.autoApproval.readPermissionDesc": "File read access inside and outside workspace", + "migration.select.autoApproval.writePermission": "Write Permission", + "migration.select.autoApproval.writePermissionDesc": "File write and edit access", + "migration.select.autoApproval.executePermission": "Execute Permission", + "migration.select.autoApproval.executePermissionDesc": "Terminal command execution", + "migration.select.autoApproval.mcpPermission": "MCP Permission", + "migration.select.autoApproval.mcpPermissionDesc": "MCP tool usage", + "migration.select.autoApproval.taskPermission": "Task Permission", + "migration.select.autoApproval.taskPermissionDesc": "Mode switching and subtask creation", + "migration.select.language": "UI Language", + "migration.select.languageDesc": "Your language preference will be applied to the new extension", + "migration.select.autocomplete": "Autocomplete Settings", + "migration.select.autocompleteDesc": "Auto-trigger, keybinding, and chat autocomplete preferences", + "migration.select.continue": "Continue", + "migration.select.back": "Back", + "migration.progress.title": "Migrating your settings…", + "migration.progress.done": "Continue", + "migration.complete.summary": "{{success}} of {{total}} items migrated successfully.", + "migration.complete.cleanup": "Remove legacy settings data", + "migration.complete.cleanupDescription": + "This removes the old settings from VS Code storage. You will not be able to re-run this migration.", + "migration.complete.done": "Done", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/es.ts b/packages/kilo-vscode/webview-ui/src/i18n/es.ts index fe97c810dd5..f747df257c2 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/es.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/es.ts @@ -962,4 +962,56 @@ export const dict = { "question.summary": "{{n}} de {{total}} preguntas", "common.review": "Revisar", + + // legacy-migration start + "settings.legacyMigration.link": "Migrar desde la versión heredada", + "settings.aboutKiloCode.legacyMigration.title": "Migración heredada", + "settings.aboutKiloCode.legacyMigration.description": + "Migra la configuración de una instalación anterior de Kilo Code, incluyendo las claves API de proveedores y el modelo predeterminado.", + "migration.welcome.title": "Bienvenido al nuevo Kilo Code", + "migration.welcome.detected": "Hemos detectado una configuración de una instalación anterior de Kilo Code.", + "migration.welcome.sessionsInfo": + "Las sesiones de chat y el historial no se pueden migrar — la nueva versión utiliza una arquitectura diferente.", + "migration.welcome.canMigrate": "Las siguientes configuraciones se pueden migrar a la nueva versión:", + "migration.welcome.start": "Iniciar migración", + "migration.welcome.skip": "Omitir migración", + "migration.steps.title": "Migra tu configuración", + "migration.steps.subtitle": + "Encontramos configuraciones de tu instalación anterior de Kilo Code. Elige qué deseas transferir.", + "migration.select.providers": "Claves API de proveedores", + "migration.select.mcpServers": "Servidores MCP", + "migration.select.customModes": "Modos personalizados / Agentes", + "migration.select.defaultModel": "Modelo predeterminado", + "migration.select.unsupported": "No compatible con la nueva versión", + "migration.select.nothingToMigrate": "No se encontró nada para migrar en la configuración heredada.", + "migration.select.settings": "Configuración", + "migration.select.autoApproval": "Aprobación automática", + "migration.select.autoApproval.commandRules": "Reglas de comandos", + "migration.select.autoApproval.commandRulesDesc": "Interruptor principal y listas de comandos permitidos/denegados", + "migration.select.autoApproval.readPermission": "Permiso de lectura", + "migration.select.autoApproval.readPermissionDesc": + "Acceso de lectura de archivos dentro y fuera del espacio de trabajo", + "migration.select.autoApproval.writePermission": "Permiso de escritura", + "migration.select.autoApproval.writePermissionDesc": "Acceso de escritura y edición de archivos", + "migration.select.autoApproval.executePermission": "Permiso de ejecución", + "migration.select.autoApproval.executePermissionDesc": "Ejecución de comandos en terminal", + "migration.select.autoApproval.mcpPermission": "Permiso MCP", + "migration.select.autoApproval.mcpPermissionDesc": "Uso de herramientas MCP", + "migration.select.autoApproval.taskPermission": "Permiso de tareas", + "migration.select.autoApproval.taskPermissionDesc": "Cambio de modos y creación de subtareas", + "migration.select.language": "Idioma de la interfaz", + "migration.select.languageDesc": "Tu preferencia de idioma se aplicará a la nueva extensión", + "migration.select.autocomplete": "Configuración de autocompletado", + "migration.select.autocompleteDesc": + "Preferencias de activación automática, atajos de teclado y autocompletado del chat", + "migration.select.continue": "Continuar", + "migration.select.back": "Atrás", + "migration.progress.title": "Migrando tu configuración…", + "migration.progress.done": "Continuar", + "migration.complete.summary": "{{success}} de {{total}} elementos migrados con éxito.", + "migration.complete.cleanup": "Eliminar datos de la configuración heredada", + "migration.complete.cleanupDescription": + "Esto elimina la configuración antigua del almacenamiento de VS Code. No podrás volver a ejecutar esta migración.", + "migration.complete.done": "Hecho", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/fr.ts b/packages/kilo-vscode/webview-ui/src/i18n/fr.ts index af6148b6a5e..c29b13962bf 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/fr.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/fr.ts @@ -970,4 +970,56 @@ export const dict = { "question.summary": "{{n}} sur {{total}} questions", "common.review": "Réviser", + + // legacy-migration start + "settings.legacyMigration.link": "Migrer depuis l'ancienne version", + "settings.aboutKiloCode.legacyMigration.title": "Migration de l'ancienne version", + "settings.aboutKiloCode.legacyMigration.description": + "Migrer les paramètres d'une précédente installation de Kilo Code, y compris les clés d'API des fournisseurs et le modèle par défaut.", + "migration.welcome.title": "Bienvenue dans le nouveau Kilo Code", + "migration.welcome.detected": "Nous avons détecté des paramètres d'une précédente installation de Kilo Code.", + "migration.welcome.sessionsInfo": + "Les sessions de discussion et l'historique ne peuvent pas être migrés — la nouvelle version utilise une architecture différente.", + "migration.welcome.canMigrate": "Les paramètres suivants peuvent être migrés vers la nouvelle version :", + "migration.welcome.start": "Démarrer la migration", + "migration.welcome.skip": "Ignorer la migration", + "migration.steps.title": "Migrer vos paramètres", + "migration.steps.subtitle": + "Nous avons trouvé des paramètres de votre précédente installation de Kilo Code. Choisissez ce que vous souhaitez transférer.", + "migration.select.providers": "Clés d'API des fournisseurs", + "migration.select.mcpServers": "Serveurs MCP", + "migration.select.customModes": "Modes personnalisés / Agents", + "migration.select.defaultModel": "Modèle par défaut", + "migration.select.unsupported": "Non pris en charge dans la nouvelle version", + "migration.select.nothingToMigrate": "Rien à migrer n'a été trouvé dans les anciens paramètres.", + "migration.select.settings": "Paramètres", + "migration.select.autoApproval": "Approbation automatique", + "migration.select.autoApproval.commandRules": "Règles de commande", + "migration.select.autoApproval.commandRulesDesc": "Bascule principale et listes de commandes autorisées/refusées", + "migration.select.autoApproval.readPermission": "Autorisation de lecture", + "migration.select.autoApproval.readPermissionDesc": + "Accès en lecture aux fichiers à l'intérieur et à l'extérieur de l'espace de travail", + "migration.select.autoApproval.writePermission": "Autorisation d'écriture", + "migration.select.autoApproval.writePermissionDesc": "Accès en écriture et modification de fichiers", + "migration.select.autoApproval.executePermission": "Autorisation d'exécution", + "migration.select.autoApproval.executePermissionDesc": "Exécution de commandes dans le terminal", + "migration.select.autoApproval.mcpPermission": "Autorisation MCP", + "migration.select.autoApproval.mcpPermissionDesc": "Utilisation d'outils MCP", + "migration.select.autoApproval.taskPermission": "Autorisation de tâche", + "migration.select.autoApproval.taskPermissionDesc": "Changement de mode et création de sous-tâches", + "migration.select.language": "Langue de l'interface", + "migration.select.languageDesc": "Votre préférence de langue sera appliquée à la nouvelle extension", + "migration.select.autocomplete": "Paramètres de saisie semi-automatique", + "migration.select.autocompleteDesc": + "Préférences de déclenchement automatique, de raccourcis clavier et de saisie semi-automatique du chat", + "migration.select.continue": "Continuer", + "migration.select.back": "Retour", + "migration.progress.title": "Migration de vos paramètres…", + "migration.progress.done": "Continuer", + "migration.complete.summary": "{{success}} éléments sur {{total}} migrés avec succès.", + "migration.complete.cleanup": "Supprimer les données des anciens paramètres", + "migration.complete.cleanupDescription": + "Cela supprime les anciens paramètres du stockage de VS Code. Vous ne pourrez pas réexécuter cette migration.", + "migration.complete.done": "Terminé", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ja.ts b/packages/kilo-vscode/webview-ui/src/i18n/ja.ts index f780e706d88..2057086a8d8 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ja.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ja.ts @@ -950,4 +950,53 @@ export const dict = { "question.summary": "{{total}} 問中 {{n}} 問目", "common.review": "確認", + + // legacy-migration start + "settings.legacyMigration.link": "レガシーバージョンからの移行", + "settings.aboutKiloCode.legacyMigration.title": "レガシー移行", + "settings.aboutKiloCode.legacyMigration.description": + "プロバイダーのAPIキーやデフォルトモデルなど、以前にインストールしたKilo Codeから設定を移行します。", + "migration.welcome.title": "新しいKilo Codeへようこそ", + "migration.welcome.detected": "以前にインストールされたKilo Codeの設定を検出しました。", + "migration.welcome.sessionsInfo": + "チャットセッションと履歴は移行できません — 新しいバージョンでは異なるアーキテクチャが使用されています。", + "migration.welcome.canMigrate": "以下の設定を新しいバージョンに移行できます:", + "migration.welcome.start": "移行を開始", + "migration.welcome.skip": "移行をスキップ", + "migration.steps.title": "設定の移行", + "migration.steps.subtitle": "以前のKilo Codeインストールの設定が見つかりました。引き継ぐ項目を選択してください。", + "migration.select.providers": "プロバイダーのAPIキー", + "migration.select.mcpServers": "MCPサーバー", + "migration.select.customModes": "カスタムモード / エージェント", + "migration.select.defaultModel": "デフォルトモデル", + "migration.select.unsupported": "新しいバージョンではサポートされていません", + "migration.select.nothingToMigrate": "レガシー設定に移行する項目が見つかりませんでした。", + "migration.select.settings": "設定", + "migration.select.autoApproval": "自動承認", + "migration.select.autoApproval.commandRules": "コマンドルール", + "migration.select.autoApproval.commandRulesDesc": "マスタートグルと許可/拒否されたコマンドリスト", + "migration.select.autoApproval.readPermission": "読み取り権限", + "migration.select.autoApproval.readPermissionDesc": "ワークスペース内外のファイル読み取りアクセス", + "migration.select.autoApproval.writePermission": "書き込み権限", + "migration.select.autoApproval.writePermissionDesc": "ファイルの書き込みと編集アクセス", + "migration.select.autoApproval.executePermission": "実行権限", + "migration.select.autoApproval.executePermissionDesc": "ターミナルコマンドの実行", + "migration.select.autoApproval.mcpPermission": "MCP権限", + "migration.select.autoApproval.mcpPermissionDesc": "MCPツールの使用", + "migration.select.autoApproval.taskPermission": "タスク権限", + "migration.select.autoApproval.taskPermissionDesc": "モードの切り替えとサブタスクの作成", + "migration.select.language": "UI言語", + "migration.select.languageDesc": "言語設定は新しい拡張機能に適用されます", + "migration.select.autocomplete": "オートコンプリート設定", + "migration.select.autocompleteDesc": "自動トリガー、キーバインド、およびチャットのオートコンプリート設定", + "migration.select.continue": "続行", + "migration.select.back": "戻る", + "migration.progress.title": "設定を移行しています…", + "migration.progress.done": "続行", + "migration.complete.summary": "{{total}}個中{{success}}個の項目が正常に移行されました。", + "migration.complete.cleanup": "レガシー設定データを削除する", + "migration.complete.cleanupDescription": + "VS Codeのストレージから古い設定を削除します。この移行を再度実行することはできなくなります。", + "migration.complete.done": "完了", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ko.ts b/packages/kilo-vscode/webview-ui/src/i18n/ko.ts index 358e367bf1d..b5cb0dcd702 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ko.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ko.ts @@ -951,4 +951,53 @@ export const dict = { "question.summary": "{{total}}개 질문 중 {{n}}번째", "common.review": "검토", + + // legacy-migration start + "settings.legacyMigration.link": "레거시 버전에서 마이그레이션", + "settings.aboutKiloCode.legacyMigration.title": "레거시 마이그레이션", + "settings.aboutKiloCode.legacyMigration.description": + "공급자 API 키 및 기본 모델을 포함하여 이전 Kilo Code 설치에서 설정을 마이그레이션합니다.", + "migration.welcome.title": "새로운 Kilo Code에 오신 것을 환영합니다", + "migration.welcome.detected": "이전 Kilo Code 설치의 설정이 감지되었습니다.", + "migration.welcome.sessionsInfo": + "채팅 세션 및 기록은 마이그레이션할 수 없습니다 — 새 버전은 다른 아키텍처를 사용합니다.", + "migration.welcome.canMigrate": "다음 설정은 새 버전으로 마이그레이션할 수 있습니다:", + "migration.welcome.start": "마이그레이션 시작", + "migration.welcome.skip": "마이그레이션 건너뛰기", + "migration.steps.title": "설정 마이그레이션", + "migration.steps.subtitle": "이전 Kilo Code 설치에서 설정을 찾았습니다. 가져올 항목을 선택하세요.", + "migration.select.providers": "공급자 API 키", + "migration.select.mcpServers": "MCP 서버", + "migration.select.customModes": "사용자 지정 모드 / 에이전트", + "migration.select.defaultModel": "기본 모델", + "migration.select.unsupported": "새 버전에서는 지원되지 않음", + "migration.select.nothingToMigrate": "레거시 설정에서 마이그레이션할 항목을 찾지 못했습니다.", + "migration.select.settings": "설정", + "migration.select.autoApproval": "자동 승인", + "migration.select.autoApproval.commandRules": "명령 규칙", + "migration.select.autoApproval.commandRulesDesc": "마스터 토글 및 허용/거부된 명령 목록", + "migration.select.autoApproval.readPermission": "읽기 권한", + "migration.select.autoApproval.readPermissionDesc": "작업 공간 내부 및 외부의 파일 읽기 액세스", + "migration.select.autoApproval.writePermission": "쓰기 권한", + "migration.select.autoApproval.writePermissionDesc": "파일 쓰기 및 편집 액세스", + "migration.select.autoApproval.executePermission": "실행 권한", + "migration.select.autoApproval.executePermissionDesc": "터미널 명령 실행", + "migration.select.autoApproval.mcpPermission": "MCP 권한", + "migration.select.autoApproval.mcpPermissionDesc": "MCP 도구 사용", + "migration.select.autoApproval.taskPermission": "작업 권한", + "migration.select.autoApproval.taskPermissionDesc": "모드 전환 및 하위 작업 생성", + "migration.select.language": "UI 언어", + "migration.select.languageDesc": "언어 기본 설정이 새 확장 프로그램에 적용됩니다", + "migration.select.autocomplete": "자동 완성 설정", + "migration.select.autocompleteDesc": "자동 트리거, 키 바인딩 및 채팅 자동 완성 기본 설정", + "migration.select.continue": "계속", + "migration.select.back": "뒤로", + "migration.progress.title": "설정을 마이그레이션하는 중…", + "migration.progress.done": "계속", + "migration.complete.summary": "{{total}}개 중 {{success}}개 항목이 성공적으로 마이그레이션되었습니다.", + "migration.complete.cleanup": "레거시 설정 데이터 제거", + "migration.complete.cleanupDescription": + "이 작업은 VS Code 저장소에서 이전 설정을 제거합니다. 이 마이그레이션을 다시 실행할 수 없게 됩니다.", + "migration.complete.done": "완료", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/no.ts b/packages/kilo-vscode/webview-ui/src/i18n/no.ts index 40cf8db9f4e..3bc89db2d08 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/no.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/no.ts @@ -956,4 +956,54 @@ export const dict = { "question.summary": "{{n}} av {{total}} spørsmål", "common.review": "Gjennomgå", + + // legacy-migration start + "settings.legacyMigration.link": "Migrer fra eldre versjon", + "settings.aboutKiloCode.legacyMigration.title": "Migrering fra eldre versjon", + "settings.aboutKiloCode.legacyMigration.description": + "Migrer innstillinger fra en tidligere installasjon av Kilo Code, inkludert API-nøkler for leverandører og standardmodell.", + "migration.welcome.title": "Velkommen til nye Kilo Code", + "migration.welcome.detected": "Vi oppdaget innstillinger fra en tidligere installasjon av Kilo Code.", + "migration.welcome.sessionsInfo": + "Chatøkter og historikk kan ikke migreres — den nye versjonen bruker en annen arkitektur.", + "migration.welcome.canMigrate": "Følgende innstillinger kan migreres til den nye versjonen:", + "migration.welcome.start": "Start migrering", + "migration.welcome.skip": "Hopp over migrering", + "migration.steps.title": "Migrer innstillingene dine", + "migration.steps.subtitle": + "Vi fant innstillinger fra din tidligere Kilo Code-installasjon. Velg hva du vil ta med over.", + "migration.select.providers": "API-nøkler for leverandører", + "migration.select.mcpServers": "MCP-servere", + "migration.select.customModes": "Egendefinerte moduser / Agenter", + "migration.select.defaultModel": "Standardmodell", + "migration.select.unsupported": "Støttes ikke i ny versjon", + "migration.select.nothingToMigrate": "Ingenting å migrere ble funnet i de eldre innstillingene.", + "migration.select.settings": "Innstillinger", + "migration.select.autoApproval": "Automatisk godkjenning", + "migration.select.autoApproval.commandRules": "Kommandoregler", + "migration.select.autoApproval.commandRulesDesc": "Hovedbryter og lister for tillatte/avviste kommandoer", + "migration.select.autoApproval.readPermission": "Lesetillatelse", + "migration.select.autoApproval.readPermissionDesc": "Lesetilgang for filer i og utenfor arbeidsområdet", + "migration.select.autoApproval.writePermission": "Skrivetillatelse", + "migration.select.autoApproval.writePermissionDesc": "Skrive- og redigeringstilgang for filer", + "migration.select.autoApproval.executePermission": "Utførelsestillatelse", + "migration.select.autoApproval.executePermissionDesc": "Kjøring av terminalkommandoer", + "migration.select.autoApproval.mcpPermission": "MCP-tillatelse", + "migration.select.autoApproval.mcpPermissionDesc": "Bruk av MCP-verktøy", + "migration.select.autoApproval.taskPermission": "Oppgavetillatelse", + "migration.select.autoApproval.taskPermissionDesc": "Modusbytte og opprettelse av underoppgaver", + "migration.select.language": "UI-språk", + "migration.select.languageDesc": "Din språkpreferanse vil bli brukt i den nye utvidelsen", + "migration.select.autocomplete": "Innstillinger for autofullføring", + "migration.select.autocompleteDesc": "Preferanser for autoutløsing, hurtigtaster og autofullføring i chat", + "migration.select.continue": "Fortsett", + "migration.select.back": "Tilbake", + "migration.progress.title": "Migrerer innstillingene dine…", + "migration.progress.done": "Fortsett", + "migration.complete.summary": "{{success}} av {{total}} elementer ble migrert.", + "migration.complete.cleanup": "Fjern eldre innstillingsdata", + "migration.complete.cleanupDescription": + "Dette fjerner de gamle innstillingene fra VS Code-lagringen. Du vil ikke kunne kjøre denne migreringen på nytt.", + "migration.complete.done": "Ferdig", + // legacy-migration end } satisfies Partial> diff --git a/packages/kilo-vscode/webview-ui/src/i18n/pl.ts b/packages/kilo-vscode/webview-ui/src/i18n/pl.ts index f81d26173d9..3bd53a91631 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/pl.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/pl.ts @@ -957,4 +957,56 @@ export const dict = { "question.summary": "{{n}} z {{total}} pytań", "common.review": "Przejrzyj", + + // legacy-migration start + "settings.legacyMigration.link": "Migracja ze starszej wersji", + "settings.aboutKiloCode.legacyMigration.title": "Migracja starszej wersji", + "settings.aboutKiloCode.legacyMigration.description": + "Migruj ustawienia z poprzedniej instalacji Kilo Code, w tym klucze API dostawców i domyślny model.", + "migration.welcome.title": "Witamy w nowym Kilo Code", + "migration.welcome.detected": "Wykryliśmy ustawienia z poprzedniej instalacji Kilo Code.", + "migration.welcome.sessionsInfo": + "Sesje czatu i historia nie mogą zostać zmigrowane — nowa wersja wykorzystuje inną architekturę.", + "migration.welcome.canMigrate": "Następujące ustawienia mogą zostać zmigrowane do nowej wersji:", + "migration.welcome.start": "Rozpocznij migrację", + "migration.welcome.skip": "Pomiń migrację", + "migration.steps.title": "Migruj swoje ustawienia", + "migration.steps.subtitle": + "Znaleźliśmy ustawienia z poprzedniej instalacji Kilo Code. Wybierz, co chcesz przenieść.", + "migration.select.providers": "Klucze API dostawców", + "migration.select.mcpServers": "Serwery MCP", + "migration.select.customModes": "Niestandardowe tryby / Agenci", + "migration.select.defaultModel": "Domyślny model", + "migration.select.unsupported": "Nieobsługiwane w nowej wersji", + "migration.select.nothingToMigrate": "W starszych ustawieniach nie znaleziono niczego do zmigrowania.", + "migration.select.settings": "Ustawienia", + "migration.select.autoApproval": "Automatyczne zatwierdzanie", + "migration.select.autoApproval.commandRules": "Reguły poleceń", + "migration.select.autoApproval.commandRulesDesc": "Główny przełącznik oraz listy dozwolonych/zabronionych poleceń", + "migration.select.autoApproval.readPermission": "Uprawnienia odczytu", + "migration.select.autoApproval.readPermissionDesc": + "Dostęp do odczytu plików wewnątrz i na zewnątrz obszaru roboczego", + "migration.select.autoApproval.writePermission": "Uprawnienia zapisu", + "migration.select.autoApproval.writePermissionDesc": "Dostęp do zapisu i edycji plików", + "migration.select.autoApproval.executePermission": "Uprawnienia wykonywania", + "migration.select.autoApproval.executePermissionDesc": "Wykonywanie poleceń terminala", + "migration.select.autoApproval.mcpPermission": "Uprawnienia MCP", + "migration.select.autoApproval.mcpPermissionDesc": "Korzystanie z narzędzi MCP", + "migration.select.autoApproval.taskPermission": "Uprawnienia zadań", + "migration.select.autoApproval.taskPermissionDesc": "Przełączanie trybów i tworzenie podzadań", + "migration.select.language": "Język interfejsu", + "migration.select.languageDesc": "Twoje preferencje językowe zostaną zastosowane w nowym rozszerzeniu", + "migration.select.autocomplete": "Ustawienia autouzupełniania", + "migration.select.autocompleteDesc": + "Preferencje automatycznego wyzwalania, skrótów klawiszowych i autouzupełniania na czacie", + "migration.select.continue": "Kontynuuj", + "migration.select.back": "Wstecz", + "migration.progress.title": "Migrowanie Twoich ustawień…", + "migration.progress.done": "Kontynuuj", + "migration.complete.summary": "Pomyślnie zmigrowano {{success}} z {{total}} elementów.", + "migration.complete.cleanup": "Usuń dane starszych ustawień", + "migration.complete.cleanupDescription": + "Spowoduje to usunięcie starych ustawień z magazynu VS Code. Nie będzie można ponownie uruchomić tej migracji.", + "migration.complete.done": "Gotowe", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/ru.ts b/packages/kilo-vscode/webview-ui/src/i18n/ru.ts index 5459a9bfe8d..96121ffc727 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/ru.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/ru.ts @@ -959,4 +959,55 @@ export const dict = { "question.summary": "{{n}} из {{total}} вопросов", "common.review": "Просмотр", + + // legacy-migration start + "settings.legacyMigration.link": "Миграция с устаревшей версии", + "settings.aboutKiloCode.legacyMigration.title": "Миграция с устаревшей версии", + "settings.aboutKiloCode.legacyMigration.description": + "Перенос настроек из предыдущей установки Kilo Code, включая API-ключи провайдеров и модель по умолчанию.", + "migration.welcome.title": "Добро пожаловать в новый Kilo Code", + "migration.welcome.detected": "Мы обнаружили настройки от предыдущей установки Kilo Code.", + "migration.welcome.sessionsInfo": + "Сессии чата и история не могут быть перенесены — новая версия использует другую архитектуру.", + "migration.welcome.canMigrate": "В новую версию можно перенести следующие настройки:", + "migration.welcome.start": "Начать миграцию", + "migration.welcome.skip": "Пропустить миграцию", + "migration.steps.title": "Перенос ваших настроек", + "migration.steps.subtitle": + "Мы нашли настройки от вашей предыдущей установки Kilo Code. Выберите, что нужно перенести.", + "migration.select.providers": "API-ключи провайдеров", + "migration.select.mcpServers": "Серверы MCP", + "migration.select.customModes": "Пользовательские режимы / Агенты", + "migration.select.defaultModel": "Модель по умолчанию", + "migration.select.unsupported": "Не поддерживается в новой версии", + "migration.select.nothingToMigrate": "В старых настройках не найдено данных для переноса.", + "migration.select.settings": "Настройки", + "migration.select.autoApproval": "Автоматическое подтверждение", + "migration.select.autoApproval.commandRules": "Правила команд", + "migration.select.autoApproval.commandRulesDesc": "Главный переключатель и списки разрешенных/запрещенных команд", + "migration.select.autoApproval.readPermission": "Разрешение на чтение", + "migration.select.autoApproval.readPermissionDesc": "Доступ к чтению файлов внутри и вне рабочей области", + "migration.select.autoApproval.writePermission": "Разрешение на запись", + "migration.select.autoApproval.writePermissionDesc": "Доступ к записи и редактированию файлов", + "migration.select.autoApproval.executePermission": "Разрешение на выполнение", + "migration.select.autoApproval.executePermissionDesc": "Выполнение команд в терминале", + "migration.select.autoApproval.mcpPermission": "Разрешение MCP", + "migration.select.autoApproval.mcpPermissionDesc": "Использование инструментов MCP", + "migration.select.autoApproval.taskPermission": "Разрешение на задачи", + "migration.select.autoApproval.taskPermissionDesc": "Переключение режимов и создание подзадач", + "migration.select.language": "Язык интерфейса", + "migration.select.languageDesc": "Ваши языковые настройки будут применены к новому расширению", + "migration.select.autocomplete": "Настройки автодополнения", + "migration.select.autocompleteDesc": + "Параметры автоматического срабатывания, горячие клавиши и автодополнение в чате", + "migration.select.continue": "Продолжить", + "migration.select.back": "Назад", + "migration.progress.title": "Перенос ваших настроек…", + "migration.progress.done": "Продолжить", + "migration.complete.summary": "Успешно перенесено: {{success}} из {{total}} элементов.", + "migration.complete.cleanup": "Удалить данные старых настроек", + "migration.complete.cleanupDescription": + "Это удалит старые настройки из хранилища VS Code. Вы не сможете запустить эту миграцию повторно.", + "migration.complete.done": "Готово", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/th.ts b/packages/kilo-vscode/webview-ui/src/i18n/th.ts index 3f8a4d48388..ef7c5117d1d 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/th.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/th.ts @@ -943,4 +943,53 @@ export const dict = { "question.summary": "{{n}} จาก {{total}} คำถาม", "common.review": "ตรวจสอบ", + + // legacy-migration start + "settings.legacyMigration.link": "ย้ายข้อมูลจากเวอร์ชันดั้งเดิม", + "settings.aboutKiloCode.legacyMigration.title": "การย้ายข้อมูลจากเวอร์ชันดั้งเดิม", + "settings.aboutKiloCode.legacyMigration.description": + "ย้ายการตั้งค่าจากการติดตั้ง Kilo Code ก่อนหน้านี้ รวมถึงคีย์ API ของผู้ให้บริการและโมเดลเริ่มต้น", + "migration.welcome.title": "ยินดีต้อนรับสู่ Kilo Code โฉมใหม่", + "migration.welcome.detected": "เราตรวจพบการตั้งค่าจากการติดตั้ง Kilo Code ก่อนหน้านี้", + "migration.welcome.sessionsInfo": "ไม่สามารถย้ายเซสชันการแชทและประวัติได้ — เวอร์ชันใหม่ใช้สถาปัตยกรรมที่แตกต่างกัน", + "migration.welcome.canMigrate": "การตั้งค่าต่อไปนี้สามารถย้ายไปยังเวอร์ชันใหม่ได้:", + "migration.welcome.start": "เริ่มการย้ายข้อมูล", + "migration.welcome.skip": "ข้ามการย้ายข้อมูล", + "migration.steps.title": "ย้ายการตั้งค่าของคุณ", + "migration.steps.subtitle": "เราพบการตั้งค่าจากการติดตั้ง Kilo Code ก่อนหน้านี้ของคุณ เลือกสิ่งที่จะนำเข้ามาด้วย", + "migration.select.providers": "คีย์ API ของผู้ให้บริการ", + "migration.select.mcpServers": "เซิร์ฟเวอร์ MCP", + "migration.select.customModes": "โหมดกำหนดเอง / Agents", + "migration.select.defaultModel": "โมเดลเริ่มต้น", + "migration.select.unsupported": "ไม่รองรับในเวอร์ชันใหม่", + "migration.select.nothingToMigrate": "ไม่พบสิ่งที่จะย้ายในการตั้งค่าดั้งเดิม", + "migration.select.settings": "การตั้งค่า", + "migration.select.autoApproval": "การอนุมัติอัตโนมัติ", + "migration.select.autoApproval.commandRules": "กฎคำสั่ง", + "migration.select.autoApproval.commandRulesDesc": "สวิตช์หลักและรายการคำสั่งที่อนุญาต/ปฏิเสธ", + "migration.select.autoApproval.readPermission": "สิทธิ์การอ่าน", + "migration.select.autoApproval.readPermissionDesc": "การเข้าถึงการอ่านไฟล์ภายในและภายนอกเวิร์กสเปซ", + "migration.select.autoApproval.writePermission": "สิทธิ์การเขียน", + "migration.select.autoApproval.writePermissionDesc": "การเข้าถึงการเขียนและแก้ไขไฟล์", + "migration.select.autoApproval.executePermission": "สิทธิ์การดำเนินการ", + "migration.select.autoApproval.executePermissionDesc": "การเรียกใช้งานคำสั่ง Terminal", + "migration.select.autoApproval.mcpPermission": "สิทธิ์ MCP", + "migration.select.autoApproval.mcpPermissionDesc": "การใช้งานเครื่องมือ MCP", + "migration.select.autoApproval.taskPermission": "สิทธิ์งาน", + "migration.select.autoApproval.taskPermissionDesc": "การสลับโหมดและการสร้างงานย่อย", + "migration.select.language": "ภาษา UI", + "migration.select.languageDesc": "การตั้งค่าภาษาของคุณจะถูกนำไปใช้กับส่วนขยายใหม่", + "migration.select.autocomplete": "การตั้งค่าเติมข้อความอัตโนมัติ", + "migration.select.autocompleteDesc": + "การเรียกใช้อัตโนมัติ, การผูกแป้นพิมพ์ และการตั้งค่าการเติมข้อความอัตโนมัติในการแชท", + "migration.select.continue": "ดำเนินการต่อ", + "migration.select.back": "ย้อนกลับ", + "migration.progress.title": "กำลังย้ายการตั้งค่าของคุณ…", + "migration.progress.done": "ดำเนินการต่อ", + "migration.complete.summary": "ย้ายรายการสำเร็จ {{success}} จาก {{total}} รายการ", + "migration.complete.cleanup": "ลบข้อมูลการตั้งค่าดั้งเดิม", + "migration.complete.cleanupDescription": + "การดำเนินการนี้จะลบการตั้งค่าเก่าออกจากพื้นที่เก็บข้อมูลของ VS Code คุณจะไม่สามารถเรียกใช้การย้ายข้อมูลนี้ซ้ำได้อีก", + "migration.complete.done": "เสร็จสิ้น", + // legacy-migration end } diff --git a/packages/kilo-vscode/webview-ui/src/i18n/zh.ts b/packages/kilo-vscode/webview-ui/src/i18n/zh.ts index 970340c0da2..6d6c238b212 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/zh.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/zh.ts @@ -946,4 +946,51 @@ export const dict = { "question.summary": "第 {{n}} / {{total}} 个问题", "common.review": "审查", + + // legacy-migration start + "settings.legacyMigration.link": "从旧版本迁移", + "settings.aboutKiloCode.legacyMigration.title": "旧版本迁移", + "settings.aboutKiloCode.legacyMigration.description": + "从之前安装的 Kilo Code 迁移设置,包括提供商 API 密钥和默认模型。", + "migration.welcome.title": "欢迎使用全新 Kilo Code", + "migration.welcome.detected": "我们检测到了来自之前安装的 Kilo Code 的设置。", + "migration.welcome.sessionsInfo": "聊天会话和历史记录无法迁移 — 新版本使用了不同的架构。", + "migration.welcome.canMigrate": "以下设置可以迁移到新版本:", + "migration.welcome.start": "开始迁移", + "migration.welcome.skip": "跳过迁移", + "migration.steps.title": "迁移您的设置", + "migration.steps.subtitle": "我们发现了您之前 Kilo Code 安装的设置。请选择要引入的内容。", + "migration.select.providers": "提供商 API 密钥", + "migration.select.mcpServers": "MCP 服务器", + "migration.select.customModes": "自定义模式 / 智能体", + "migration.select.defaultModel": "默认模型", + "migration.select.unsupported": "新版本不支持", + "migration.select.nothingToMigrate": "在旧版设置中未找到要迁移的内容。", + "migration.select.settings": "设置", + "migration.select.autoApproval": "自动批准", + "migration.select.autoApproval.commandRules": "命令规则", + "migration.select.autoApproval.commandRulesDesc": "主开关以及允许/拒绝的命令列表", + "migration.select.autoApproval.readPermission": "读取权限", + "migration.select.autoApproval.readPermissionDesc": "工作区内外文件读取访问权限", + "migration.select.autoApproval.writePermission": "写入权限", + "migration.select.autoApproval.writePermissionDesc": "文件写入和编辑访问权限", + "migration.select.autoApproval.executePermission": "执行权限", + "migration.select.autoApproval.executePermissionDesc": "终端命令执行", + "migration.select.autoApproval.mcpPermission": "MCP 权限", + "migration.select.autoApproval.mcpPermissionDesc": "MCP 工具使用", + "migration.select.autoApproval.taskPermission": "任务权限", + "migration.select.autoApproval.taskPermissionDesc": "模式切换和子任务创建", + "migration.select.language": "UI 语言", + "migration.select.languageDesc": "您的语言偏好将应用于新的扩展", + "migration.select.autocomplete": "自动补全设置", + "migration.select.autocompleteDesc": "自动触发、键绑定和聊天自动补全偏好设置", + "migration.select.continue": "继续", + "migration.select.back": "返回", + "migration.progress.title": "正在迁移您的设置…", + "migration.progress.done": "继续", + "migration.complete.summary": "{{total}} 项中的 {{success}} 项已成功迁移。", + "migration.complete.cleanup": "移除旧版设置数据", + "migration.complete.cleanupDescription": "这将从 VS Code 存储中移除旧设置。您将无法再次运行此迁移。", + "migration.complete.done": "完成", + // legacy-migration end } satisfies Partial> diff --git a/packages/kilo-vscode/webview-ui/src/i18n/zht.ts b/packages/kilo-vscode/webview-ui/src/i18n/zht.ts index fa8e16b4f83..9678d6a8bca 100644 --- a/packages/kilo-vscode/webview-ui/src/i18n/zht.ts +++ b/packages/kilo-vscode/webview-ui/src/i18n/zht.ts @@ -971,4 +971,51 @@ export const dict = { "question.summary": "第 {{n}} / {{total}} 個問題", "common.review": "審查", + + // legacy-migration start + "settings.legacyMigration.link": "從舊版轉移", + "settings.aboutKiloCode.legacyMigration.title": "舊版轉移", + "settings.aboutKiloCode.legacyMigration.description": + "從先前安裝的 Kilo Code 轉移設定,包含供應商 API 金鑰與預設模型。", + "migration.welcome.title": "歡迎使用全新的 Kilo Code", + "migration.welcome.detected": "我們偵測到先前安裝的 Kilo Code 設定。", + "migration.welcome.sessionsInfo": "聊天對話與歷史紀錄無法轉移 — 新版本使用了不同的架構。", + "migration.welcome.canMigrate": "下列設定可以轉移至新版本:", + "migration.welcome.start": "開始轉移", + "migration.welcome.skip": "略過轉移", + "migration.steps.title": "轉移您的設定", + "migration.steps.subtitle": "我們找到了您先前 Kilo Code 安裝的設定。請選擇要保留的項目。", + "migration.select.providers": "供應商 API 金鑰", + "migration.select.mcpServers": "MCP 伺服器", + "migration.select.customModes": "自訂模式 / 代理", + "migration.select.defaultModel": "預設模型", + "migration.select.unsupported": "新版本不支援", + "migration.select.nothingToMigrate": "在舊版設定中找不到可轉移的項目。", + "migration.select.settings": "設定", + "migration.select.autoApproval": "自動核准", + "migration.select.autoApproval.commandRules": "指令規則", + "migration.select.autoApproval.commandRulesDesc": "主要開關與允許/拒絕的指令清單", + "migration.select.autoApproval.readPermission": "讀取權限", + "migration.select.autoApproval.readPermissionDesc": "工作區內外的檔案讀取存取權", + "migration.select.autoApproval.writePermission": "寫入權限", + "migration.select.autoApproval.writePermissionDesc": "檔案寫入與編輯存取權", + "migration.select.autoApproval.executePermission": "執行權限", + "migration.select.autoApproval.executePermissionDesc": "終端機指令執行", + "migration.select.autoApproval.mcpPermission": "MCP 權限", + "migration.select.autoApproval.mcpPermissionDesc": "MCP 工具使用", + "migration.select.autoApproval.taskPermission": "任務權限", + "migration.select.autoApproval.taskPermissionDesc": "模式切換與子任務建立", + "migration.select.language": "介面語言", + "migration.select.languageDesc": "您的語言偏好將會套用至新擴充功能", + "migration.select.autocomplete": "自動完成設定", + "migration.select.autocompleteDesc": "自動觸發、按鍵綁定與聊天自動完成偏好設定", + "migration.select.continue": "繼續", + "migration.select.back": "返回", + "migration.progress.title": "正在轉移您的設定…", + "migration.progress.done": "繼續", + "migration.complete.summary": "已成功轉移 {{total}} 個項目中的 {{success}} 個。", + "migration.complete.cleanup": "移除舊版設定資料", + "migration.complete.cleanupDescription": "這將從 VS Code 儲存空間移除舊的設定。您將無法重新執行此轉移程序。", + "migration.complete.done": "完成", + // legacy-migration end } satisfies Partial> diff --git a/packages/kilo-vscode/webview-ui/src/stories/StoryProviders.tsx b/packages/kilo-vscode/webview-ui/src/stories/StoryProviders.tsx new file mode 100644 index 00000000000..2f55722e14e --- /dev/null +++ b/packages/kilo-vscode/webview-ui/src/stories/StoryProviders.tsx @@ -0,0 +1,165 @@ +/** @jsxImportSource solid-js */ +/** + * StoryProviders — wraps composite stories with all required contexts. + * + * Instead of instantiating the full VSCodeProvider → ServerProvider → SessionProvider + * chain (which requires a real extension host / SSE connection), we provide mock + * context values directly. + */ + +import { createSignal, type ParentComponent } from "solid-js" +import { DataProvider } from "@kilocode/kilo-ui/context/data" +import { DiffComponentProvider } from "@kilocode/kilo-ui/context/diff" +import { CodeComponentProvider } from "@kilocode/kilo-ui/context/code" +import { DialogProvider } from "@kilocode/kilo-ui/context/dialog" +import { MarkedProvider } from "@kilocode/kilo-ui/context/marked" +import { I18nProvider } from "@kilocode/kilo-ui/context" +import { Diff } from "@kilocode/kilo-ui/diff" +import { Code } from "@kilocode/kilo-ui/code" +import { SessionContext } from "../context/session" +import { LanguageContext } from "../context/language" +import { dict as uiEn } from "@kilocode/kilo-ui/i18n/en" +import { dict as appEn } from "../i18n/en" +import { dict as kiloEn } from "@kilocode/kilo-i18n/en" +import type { PermissionRequest, QuestionRequest } from "../types/messages" + +// Merged English dictionary (same merge order as the real LanguageProvider) +const dict: Record = { ...appEn, ...uiEn, ...kiloEn } + +function t(key: string) { + return dict[key] ?? key +} + +// --------------------------------------------------------------------------- +// Default mock data (empty session) +// --------------------------------------------------------------------------- + +export const defaultMockData = { + session: [], + session_status: {}, + session_diff: {}, + message: {} as Record, + part: {} as Record, + permission: {} as Record, + question: {}, + provider: { all: [], connected: false, default: {} }, +} + +// --------------------------------------------------------------------------- +// Mock SessionContext value — only the subset used by components +// --------------------------------------------------------------------------- + +function noop() {} + +export function mockSessionValue(overrides?: { + id?: string + permissions?: PermissionRequest[] + questions?: QuestionRequest[] + status?: string +}) { + const id = overrides?.id ?? "story-session-001" + const permissions = overrides?.permissions ?? [] + const qs = overrides?.questions ?? [] + const status = (overrides?.status ?? "idle") as "idle" | "busy" + + return { + currentSessionID: () => id, + currentSession: () => ({ id, title: "Story session", createdAt: new Date().toISOString(), updatedAt: new Date().toISOString() }), + setCurrentSessionID: noop, + sessions: () => [], + status: () => status, + statusInfo: () => ({ type: status }), + statusText: () => (status === "idle" ? undefined : "Thinking…"), + busySince: () => (status === "busy" ? Date.now() - 2000 : undefined), + loading: () => false, + messages: () => [], + userMessages: () => [], + allMessages: () => ({}), + allParts: () => ({}), + allStatusMap: () => ({}), + getParts: () => [], + todos: () => [], + permissions: () => permissions, + questions: () => qs, + questionErrors: () => new Set(), + selected: () => ({ providerID: "anthropic", modelID: "claude-sonnet-4-20250514" }), + selectModel: noop, + totalCost: () => 0, + contextUsage: () => undefined, + agents: () => [{ name: "code", description: "Code mode", mode: "primary" as const }], + selectedAgent: () => "code", + selectAgent: noop, + getSessionAgent: () => "code", + getSessionModel: () => ({ providerID: "anthropic", modelID: "claude-sonnet-4-20250514" }), + setSessionModel: noop, + setSessionAgent: noop, + variantList: () => [], + currentVariant: () => undefined, + selectVariant: noop, + sendMessage: noop, + abort: noop, + compact: noop, + respondToPermission: noop, + replyToQuestion: noop, + rejectQuestion: noop, + createSession: noop, + clearCurrentSession: noop, + loadSessions: noop, + selectSession: noop, + deleteSession: noop, + renameSession: noop, + syncSession: noop, + cloudPreviewId: () => null, + selectCloudSession: noop, + } +} + +// --------------------------------------------------------------------------- +// StoryProviders component +// --------------------------------------------------------------------------- + +interface StoryProvidersProps { + data?: any + permissions?: PermissionRequest[] + questions?: QuestionRequest[] + status?: string + sessionID?: string +} + +export const StoryProviders: ParentComponent = (props) => { + const data = () => props.data ?? defaultMockData + const session = mockSessionValue({ + id: props.sessionID, + permissions: props.permissions, + questions: props.questions, + status: props.status, + }) + const [locale] = createSignal<"en">("en") + + return ( + + "" as any, + t, + }} + > + "en", t }}> + + + + + +

{props.children}
+ + + + + + + + + ) +} diff --git a/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx new file mode 100644 index 00000000000..dca22dcd92c --- /dev/null +++ b/packages/kilo-vscode/webview-ui/src/stories/composite.stories.tsx @@ -0,0 +1,463 @@ +/** @jsxImportSource solid-js */ +/** + * Composite visual regression stories for the kilo-vscode webview. + * + * These test the *composed* UI — how kilo-ui components look together + * in the extension webview context with extension-specific styling, + * inline permission prompts, and tool card overrides. + */ + +import type { Meta, StoryObj } from "storybook-solidjs-vite" +import { For, Show } from "solid-js" +import { Part } from "@kilocode/kilo-ui/message-part" +import { BasicTool } from "@kilocode/kilo-ui/basic-tool" +import { Button } from "@kilocode/kilo-ui/button" +import type { + AssistantMessage as SDKAssistantMessage, + TextPart, + ToolPart, + Message as SDKMessage, +} from "@kilocode/sdk/v2" +import { StoryProviders, defaultMockData, mockSessionValue } from "./StoryProviders" +import { AssistantMessage } from "../components/chat/AssistantMessage" +import { registerVscodeToolOverrides } from "../components/chat/VscodeToolOverrides" +import { SessionContext } from "../context/session" +import type { PermissionRequest, QuestionRequest } from "../types/messages" + +// Register VS Code tool overrides (bash expanded by default, etc.) +registerVscodeToolOverrides() + +// --------------------------------------------------------------------------- +// Shared constants +// --------------------------------------------------------------------------- + +const SESSION_ID = "story-session-001" +const ASST_MSG_ID = "asst-msg-001" +const now = Date.now() + +const baseAssistantMessage: SDKAssistantMessage = { + id: ASST_MSG_ID, + sessionID: SESSION_ID, + role: "assistant", + parentID: "user-msg-001", + time: { created: now - 9000, completed: now - 5000 }, + modelID: "claude-sonnet-4-20250514", + providerID: "anthropic", + mode: "default", + agent: "default", + path: { cwd: "/project", root: "/project" }, + cost: 0.0023, + tokens: { total: 512, input: 256, output: 256, reasoning: 0, cache: { read: 0, write: 0 } }, +} + +// --------------------------------------------------------------------------- +// Tool parts +// --------------------------------------------------------------------------- + +const globPending: ToolPart = { + id: "part-glob-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-glob-001", + tool: "glob", + state: { + status: "pending", + input: { pattern: "**/*.md", path: "." }, + title: "Searching for files", + metadata: {}, + time: { start: now - 3000 }, + }, +} + +const readCompleted: ToolPart = { + id: "part-read-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-read-001", + tool: "read", + state: { + status: "completed", + input: { filePath: "src/main.tsx" }, + output: 'import { render } from "solid-js/web"\nrender(() => , document.getElementById("root")!)', + title: "Read file", + metadata: {}, + time: { start: now - 8000, end: now - 7500 }, + }, +} + +const grepCompleted: ToolPart = { + id: "part-grep-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-grep-001", + tool: "grep", + state: { + status: "completed", + input: { pattern: "TODO", path: "src/" }, + output: "src/main.tsx:12: // TODO: add error boundary\nsrc/utils.ts:5: // TODO: refactor", + title: "Search", + metadata: {}, + time: { start: now - 7000, end: now - 6500 }, + }, +} + +const globCompleted: ToolPart = { + id: "part-glob-002", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-glob-002", + tool: "glob", + state: { + status: "completed", + input: { pattern: "src/**/*.ts", path: "." }, + output: "src/main.ts\nsrc/utils.ts\nsrc/types.ts", + title: "Found 3 files", + metadata: {}, + time: { start: now - 6000, end: now - 5800 }, + }, +} + +const lsCompleted: ToolPart = { + id: "part-ls-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-ls-001", + tool: "ls", + state: { + status: "completed", + input: { path: "." }, + output: "src/\npackage.json\ntsconfig.json\nREADME.md", + title: "List directory", + metadata: {}, + time: { start: now - 5500, end: now - 5400 }, + }, +} + +const bashPending: ToolPart = { + id: "part-bash-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-bash-001", + tool: "bash", + state: { + status: "pending", + input: { description: "Run tests", command: "bun test" }, + title: "Execute command", + metadata: {}, + time: { start: now - 2000 }, + }, +} + +const textPart: TextPart = { + id: "part-text-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "text", + text: "I found the relevant files and will now update them.", +} + +// --------------------------------------------------------------------------- +// Permission fixtures +// --------------------------------------------------------------------------- + +const globPermission: PermissionRequest = { + id: "perm-glob-001", + sessionID: SESSION_ID, + toolName: "glob", + patterns: ["**/*.md"], + args: { pattern: "**/*.md" }, + tool: { messageID: ASST_MSG_ID, callID: "call-glob-001" }, +} + +const bashPermission: PermissionRequest = { + id: "perm-bash-001", + sessionID: SESSION_ID, + toolName: "bash", + patterns: ["bun test"], + args: { command: "bun test" }, + tool: { messageID: ASST_MSG_ID, callID: "call-bash-001" }, +} + +const dockPermission: PermissionRequest = { + id: "perm-dock-001", + sessionID: SESSION_ID, + toolName: "write", + patterns: ["src/main.tsx", "src/utils.ts"], + args: {}, + // No `tool` field — this is a non-tool (dock) permission +} + +// --------------------------------------------------------------------------- +// Question fixtures +// --------------------------------------------------------------------------- + +const questionRequest: QuestionRequest = { + id: "question-001", + sessionID: SESSION_ID, + questions: [ + { + question: "Which testing framework should I use for this project?", + header: "Choose a framework", + options: [ + { label: "Vitest", description: "Fast, Vite-native unit testing" }, + { label: "Jest", description: "Widely adopted, rich ecosystem" }, + { label: "Playwright", description: "End-to-end browser testing" }, + { label: "Bun test", description: "Built-in, zero config" }, + ], + }, + ], + tool: { messageID: ASST_MSG_ID, callID: "call-question-001" }, +} + +const questionToolPart: ToolPart = { + id: "part-question-001", + sessionID: SESSION_ID, + messageID: ASST_MSG_ID, + type: "tool", + callID: "call-question-001", + tool: "question", + state: { + status: "running", + input: { question: "Which testing framework?", options: [] }, + title: "Asking question", + metadata: {}, + time: { start: now - 1000 }, + }, +} + +// --------------------------------------------------------------------------- +// Data helpers +// --------------------------------------------------------------------------- + +function dataWith(parts: any[], permissions?: PermissionRequest[]) { + return { + ...defaultMockData, + message: { + [SESSION_ID]: [baseAssistantMessage], + }, + part: { + [ASST_MSG_ID]: parts, + }, + permission: permissions + ? { [SESSION_ID]: permissions } + : {}, + } +} + +// --------------------------------------------------------------------------- +// Meta +// --------------------------------------------------------------------------- + +const meta: Meta = { + title: "Composite/Webview", + parameters: { layout: "padded" }, +} +export default meta + +type Story = StoryObj + +// --------------------------------------------------------------------------- +// 1. Tool with inline permission (glob) +// --------------------------------------------------------------------------- + +export const GlobWithPermission: Story = { + name: "Glob + Inline Permission", + render: () => { + const perms = [globPermission] + const data = dataWith([globPending], perms) + return ( + + + + ) + }, +} + +// --------------------------------------------------------------------------- +// 2. Tool with inline permission (bash) +// --------------------------------------------------------------------------- + +export const BashWithPermission: Story = { + name: "Bash + Inline Permission", + render: () => { + const perms = [bashPermission] + const data = dataWith([bashPending], perms) + return ( + + + + ) + }, +} + +// --------------------------------------------------------------------------- +// 3. Permission dock (non-tool bottom prompt) +// --------------------------------------------------------------------------- + +export const PermissionDock: Story = { + name: "Permission Dock", + render: () => { + const perm = dockPermission + return ( + +
+ + 0}> +
+ + {(pattern) => {pattern}} + +
+
+
+
+
+ + + +
+

Approval applies only to the current session

+
+
+
+ ) + }, +} + +// --------------------------------------------------------------------------- +// 4. Tool cards — read, glob, grep, ls +// --------------------------------------------------------------------------- + +export const ToolCards: Story = { + name: "Tool Cards", + render: () => { + const data = dataWith([readCompleted, globCompleted, grepCompleted, lsCompleted]) + return ( + + + + ) + }, +} + +// --------------------------------------------------------------------------- +// 5. Chat idle — prompt input placeholder +// --------------------------------------------------------------------------- + +export const ChatIdle: Story = { + name: "Chat Idle", + render: () => ( + +
+
+
+ Ask anything… (⌘ Enter) +
+
+
+
+ ), +} + +// --------------------------------------------------------------------------- +// 6. Chat busy — working indicator, no prompt +// --------------------------------------------------------------------------- + +export const ChatBusy: Story = { + name: "Chat Busy", + render: () => { + const data = dataWith([textPart]) + return ( + +
+
+ +
+
+ + Thinking… +
+
+
+ ) + }, +} + +// --------------------------------------------------------------------------- +// 7. Multiple tool calls in one assistant message +// --------------------------------------------------------------------------- + +export const MultipleToolCalls: Story = { + name: "Multiple Tool Calls", + render: () => { + const data = dataWith([readCompleted, globCompleted, textPart]) + return ( + + + + ) + }, +} + +// --------------------------------------------------------------------------- +// 8. Inline question (tool-linked question rendered in message flow) +// --------------------------------------------------------------------------- + +export const InlineQuestion: Story = { + name: "Inline Question", + render: () => { + const qs = [questionRequest] + const data = dataWith([textPart, questionToolPart]) + return ( + + + + ) + }, +} diff --git a/packages/kilo-vscode/webview-ui/src/styles/chat.css b/packages/kilo-vscode/webview-ui/src/styles/chat.css index 821ebd623dd..68a10bfb789 100644 --- a/packages/kilo-vscode/webview-ui/src/styles/chat.css +++ b/packages/kilo-vscode/webview-ui/src/styles/chat.css @@ -696,6 +696,33 @@ word-break: break-all; } +/* Permission Prompt (inline with tool cards) */ +[data-component="tool-part-wrapper"][data-permission="true"] { + /* When wrapping a Part + permission, the outer wrapper provides the card border. + Remove the inner Part's tool-part-wrapper border so we don't get double borders. */ + > [data-component="tool-part-wrapper"] { + border: none; + border-radius: 0; + } +} + +[data-component="permission-prompt"] { + border-top: 1px solid var(--border-weak-base, var(--vscode-panel-border)); + padding: 8px 12px; +} + +[data-component="permission-prompt"] [data-slot="permission-actions"] { + display: flex; + align-items: center; + gap: 6px; +} + +[data-component="permission-prompt"] [data-slot="permission-hint"] { + font-size: 11px; + color: var(--text-weak, var(--vscode-descriptionForeground)); + margin: 4px 0 0; +} + /* Dialog Confirmation */ .dialog-confirm-body { display: flex; @@ -982,22 +1009,133 @@ } [data-slot="question-option"] { - padding: 6px 8px; - border-radius: var(--radius-lg); + display: flex; + align-items: flex-start; gap: 8px; + padding: 6px 8px; + background-color: var(--surface-raised-stronger-non-alpha); + border: 1px solid var(--border-weak-base); + border-radius: var(--radius-lg); + box-shadow: none; + text-align: left; + width: 100%; + cursor: pointer; + transition: + background-color 0.15s ease, + border-color 0.15s ease, + box-shadow 0.15s ease; + + &:hover:not([data-picked="true"]) { + background-color: var(--background-base); + } + + &[data-picked="true"] { + background-color: var(--surface-interactive-weak); + border-color: transparent; + box-shadow: var(--shadow-xs-border-hover); + } + + &:disabled { + cursor: not-allowed; + opacity: 0.6; + } + } + + [data-slot="question-option-check"] { + display: inline-flex; + transform: translateY(2px); + } + + [data-slot="question-option-box"] { + width: 16px; + height: 16px; + padding: 2px; + border-radius: var(--radius-sm); + border: 1px solid var(--border-weak-base); + display: inline-flex; + align-items: center; + justify-content: center; + flex-shrink: 0; + background-color: transparent; + transition: + background-color 0.15s ease, + border-color 0.15s ease; + + [data-component="icon"] { + opacity: 0; + color: var(--icon-base); + } + + &[data-type="radio"] { + border-radius: 999px; + } + + [data-slot="question-option-radio-dot"] { + width: 6px; + height: 6px; + border-radius: 999px; + background-color: var(--background-stronger); + opacity: 0; + } + + &[data-picked="true"] { + border-color: var(--icon-interactive-base); + + [data-component="icon"] { + opacity: 1; + color: var(--icon-invert-base); + } + + &[data-type="checkbox"] { + background-color: var(--icon-interactive-base); + } + + &[data-type="radio"] { + background-color: var(--icon-interactive-base); + [data-slot="question-option-radio-dot"] { + opacity: 1; + } + } + } + } + + [data-slot="question-option-main"] { + display: flex; + flex-direction: column; + gap: 2px; + min-width: 0; + flex: 1; } [data-slot="option-label"] { + font-family: var(--font-family-sans); font-size: var(--font-size-base); + font-weight: var(--font-weight-medium); + line-height: var(--line-height-large); + color: var(--text-strong); } [data-slot="option-description"] { + font-family: var(--font-family-sans); font-size: var(--font-size-small); + font-weight: var(--font-weight-regular); + line-height: var(--line-height-large); + color: var(--text-base); + min-width: 0; white-space: normal; overflow: visible; text-overflow: clip; } + [data-slot="question-option"][data-custom="true"] { + [data-slot="option-description"] { + overflow: visible; + text-overflow: clip; + white-space: normal; + overflow-wrap: anywhere; + } + } + [data-slot="question-review"] { display: flex; flex-direction: column; diff --git a/packages/kilo-vscode/webview-ui/src/types/messages.ts b/packages/kilo-vscode/webview-ui/src/types/messages.ts index 1eea5e3217c..d317f4f0c5c 100644 --- a/packages/kilo-vscode/webview-ui/src/types/messages.ts +++ b/packages/kilo-vscode/webview-ui/src/types/messages.ts @@ -500,7 +500,7 @@ export interface DeviceAuthCancelledMessage { export interface NavigateMessage { type: "navigate" - view: "newTask" | "marketplace" | "history" | "cloudHistory" | "profile" | "settings" + view: "newTask" | "marketplace" | "history" | "cloudHistory" | "profile" | "settings" | "migration" // legacy-migration } export interface ProvidersLoadedMessage { @@ -793,6 +793,115 @@ export interface AgentManagerSendInitialMessage { files?: Array<{ mime: string; url: string }> } +// legacy-migration start +export interface MigrationProviderInfo { + profileName: string + provider: string + model?: string + hasApiKey: boolean + supported: boolean + newProviderName?: string +} + +export interface MigrationMcpServerInfo { + name: string + type: string +} + +export interface MigrationCustomModeInfo { + name: string + slug: string +} + +export interface LegacyAutocompleteSettings { + enableAutoTrigger?: boolean + enableSmartInlineTaskKeybinding?: boolean + enableChatAutocomplete?: boolean +} + +export interface LegacySettings { + autoApprovalEnabled?: boolean + allowedCommands?: string[] + deniedCommands?: string[] + // Fine-grained auto-approval (legacy globalState keys — no prefix) + alwaysAllowReadOnly?: boolean + alwaysAllowReadOnlyOutsideWorkspace?: boolean + alwaysAllowWrite?: boolean + alwaysAllowExecute?: boolean + alwaysAllowMcp?: boolean + alwaysAllowModeSwitch?: boolean + alwaysAllowSubtasks?: boolean + language?: string + autocomplete?: LegacyAutocompleteSettings +} + +export interface MigrationResultItem { + item: string + category: "provider" | "mcpServer" | "customMode" | "defaultModel" | "settings" + status: "success" | "warning" | "error" + message?: string +} + +export interface LegacyMigrationDataMessage { + type: "legacyMigrationData" + data: { + providers: MigrationProviderInfo[] + mcpServers: MigrationMcpServerInfo[] + customModes: MigrationCustomModeInfo[] + defaultModel?: { provider: string; model: string } + settings?: LegacySettings + } +} + +export interface LegacyMigrationProgressMessage { + type: "legacyMigrationProgress" + item: string + status: "migrating" | "success" | "warning" | "error" + message?: string +} + +export interface LegacyMigrationCompleteMessage { + type: "legacyMigrationComplete" + results: MigrationResultItem[] +} + +export interface RequestLegacyMigrationDataMessage { + type: "requestLegacyMigrationData" +} + +export interface MigrationAutoApprovalSelections { + commandRules: boolean + readPermission: boolean + writePermission: boolean + executePermission: boolean + mcpPermission: boolean + taskPermission: boolean +} + +export interface StartLegacyMigrationMessage { + type: "startLegacyMigration" + selections: { + providers: string[] + mcpServers: string[] + customModes: string[] + defaultModel: boolean + settings: { + autoApproval: MigrationAutoApprovalSelections + language: boolean + autocomplete: boolean + } + } +} + +export interface SkipLegacyMigrationMessage { + type: "skipLegacyMigration" +} + +export interface ClearLegacyDataMessage { + type: "clearLegacyData" +} +// legacy-migration end + // Enhance prompt result (extension → webview) export interface EnhancePromptResultMessage { type: "enhancePromptResult" @@ -867,6 +976,11 @@ export type ExtensionMessage = | AgentManagerApplyWorktreeDiffResultMessage | AgentManagerWorktreeStatsMessage | AgentManagerLocalStatsMessage + // legacy-migration start + | LegacyMigrationDataMessage + | LegacyMigrationProgressMessage + | LegacyMigrationCompleteMessage + // legacy-migration end | EnhancePromptResultMessage | EnhancePromptErrorMessage @@ -1372,6 +1486,12 @@ export type WebviewMessage = | RequestWorktreeDiffMessage | StartDiffWatchMessage | StopDiffWatchMessage + // legacy-migration start + | RequestLegacyMigrationDataMessage + | StartLegacyMigrationMessage + | SkipLegacyMigrationMessage + | ClearLegacyDataMessage + // legacy-migration end | ApplyWorktreeDiffMessage | EnhancePromptRequest diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 63db0727e25..e31fef6dbab 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.0.36", + "version": "7.0.37", "name": "@kilocode/cli", "type": "module", "license": "MIT", diff --git a/packages/opencode/src/index.ts b/packages/opencode/src/index.ts index 825cecfd140..1eee58ad925 100644 --- a/packages/opencode/src/index.ts +++ b/packages/opencode/src/index.ts @@ -31,7 +31,7 @@ import { SessionCommand } from "./cli/cmd/session" // kilocode_change start - Import telemetry, instance disposal, and legacy migration import { Telemetry } from "@kilocode/kilo-telemetry" import { Instance } from "./project/instance" // kilocode_change -import { migrateLegacyKiloAuth, ENV_FEATURE } from "@kilocode/kilo-gateway" +import { migrateLegacyKiloAuth, ENV_FEATURE, ENV_VERSION } from "@kilocode/kilo-gateway" // kilocode_change - set feature for tracking. 'serve' is spawned by other services // (extension, cloud) which set their own KILOCODE_FEATURE env var. Direct CLI use @@ -41,6 +41,11 @@ if (!process.env[ENV_FEATURE]) { const isServe = process.argv.includes("serve") process.env[ENV_FEATURE] = isServe ? "unknown" : "cli" } + +// kilocode_change - set version so kilo-gateway can include it in the editor name header +if (!process.env[ENV_VERSION]) { + process.env[ENV_VERSION] = Installation.VERSION +} import { Config } from "./config/config" import { Auth } from "./auth" // kilocode_change end diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx index 12c3bf3057f..5d9643b8ef7 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-auto-method.tsx @@ -1,4 +1,3 @@ -// kilocode_change - Kilo Gateway TUI component /** * Custom OAuth handler for Kilo Gateway * diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-notifications.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-notifications.tsx index 6f7700d55ba..63657146ad5 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-notifications.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-notifications.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file /** * Kilo Notifications Dialog * diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-organization.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-organization.tsx index 460062675b8..877ed17ddcf 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-organization.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-organization.tsx @@ -1,4 +1,3 @@ -// kilocode_change - Kilo Gateway TUI component /** * Kilo Gateway Organization Selection Dialog * diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-profile.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-profile.tsx index 228be5a44a0..468484ed0ff 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-profile.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-profile.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file /** * Kilo Gateway Profile Dialog * diff --git a/packages/opencode/src/kilocode/components/dialog-kilo-team-select.tsx b/packages/opencode/src/kilocode/components/dialog-kilo-team-select.tsx index a5868bdc2fe..2fe5c5fedac 100644 --- a/packages/opencode/src/kilocode/components/dialog-kilo-team-select.tsx +++ b/packages/opencode/src/kilocode/components/dialog-kilo-team-select.tsx @@ -1,4 +1,3 @@ -// kilocode_change - Kilo Gateway TUI component /** * Kilo Gateway Team Selection Dialog * diff --git a/packages/opencode/src/kilocode/components/kilo-news.tsx b/packages/opencode/src/kilocode/components/kilo-news.tsx index dc74da69131..6c5508de459 100644 --- a/packages/opencode/src/kilocode/components/kilo-news.tsx +++ b/packages/opencode/src/kilocode/components/kilo-news.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file /** * Kilo News Component * diff --git a/packages/opencode/src/kilocode/components/notification-banner.tsx b/packages/opencode/src/kilocode/components/notification-banner.tsx index d0df494b031..f03ddfa47a4 100644 --- a/packages/opencode/src/kilocode/components/notification-banner.tsx +++ b/packages/opencode/src/kilocode/components/notification-banner.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file /** * Kilo Notification Banner * diff --git a/packages/opencode/src/kilocode/components/tips.tsx b/packages/opencode/src/kilocode/components/tips.tsx index fcd1f3d4ae2..65218fe7043 100644 --- a/packages/opencode/src/kilocode/components/tips.tsx +++ b/packages/opencode/src/kilocode/components/tips.tsx @@ -1,4 +1,3 @@ -// kilocode_change - new file import { For } from "solid-js" import { DEFAULT_THEMES, useTheme } from "@tui/context/theme" diff --git a/packages/opencode/src/kilocode/config-injector.ts b/packages/opencode/src/kilocode/config-injector.ts index 43488791da5..9aadd7e8a3d 100644 --- a/packages/opencode/src/kilocode/config-injector.ts +++ b/packages/opencode/src/kilocode/config-injector.ts @@ -1,8 +1,8 @@ import { Config } from "../config/config" import { ModesMigrator } from "./modes-migrator" -import { RulesMigrator } from "./rules-migrator" // kilocode_change +import { RulesMigrator } from "./rules-migrator" import { WorkflowsMigrator } from "./workflows-migrator" -import { IgnoreMigrator } from "./ignore-migrator" // kilocode_change +import { IgnoreMigrator } from "./ignore-migrator" export namespace KilocodeConfigInjector { export interface InjectionResult { @@ -46,7 +46,6 @@ export namespace KilocodeConfigInjector { config.command = workflowsMigration.commands } - // kilocode_change start - Rules migration if (options.includeRules !== false) { const rulesMigration = await RulesMigrator.migrate({ projectDir: options.projectDir, @@ -60,9 +59,7 @@ export namespace KilocodeConfigInjector { config.instructions = rulesMigration.instructions } } - // kilocode_change end - // kilocode_change start - Ignore migration if (options.includeIgnore !== false) { const ignoreMigration = await IgnoreMigrator.migrate({ projectDir: options.projectDir, @@ -75,7 +72,6 @@ export namespace KilocodeConfigInjector { config.permission = mergePermissions(config.permission, ignoreMigration.permission) } } - // kilocode_change end return { configJson: JSON.stringify(config), diff --git a/packages/opencode/src/kilocode/const.ts b/packages/opencode/src/kilocode/const.ts index 8f499daee99..605c09e4f12 100644 --- a/packages/opencode/src/kilocode/const.ts +++ b/packages/opencode/src/kilocode/const.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import { Installation } from "@/installation" diff --git a/packages/opencode/src/kilocode/dispose.ts b/packages/opencode/src/kilocode/dispose.ts new file mode 100644 index 00000000000..7f62dcbc494 --- /dev/null +++ b/packages/opencode/src/kilocode/dispose.ts @@ -0,0 +1,20 @@ +// kilocode_change - new file +/** + * Debounced Instance.disposeAll() helper. + * + * Bulk operations like legacy migration call client.auth.set() for each provider + * in rapid succession. Calling Instance.disposeAll() immediately on every auth + * change causes repeated disposal/recreation cycles. This module coalesces all + * dispose requests within a 300ms window into a single disposal call. + */ +import { Instance } from "../project/instance" + +let timer: ReturnType | undefined + +export function scheduleDisposeAll() { + if (timer) clearTimeout(timer) + timer = setTimeout(() => { + timer = undefined + void Instance.disposeAll().catch(() => undefined) + }, 300) +} diff --git a/packages/opencode/src/kilocode/enhance-prompt.ts b/packages/opencode/src/kilocode/enhance-prompt.ts index 72fd1a47d03..c6246a5a28e 100644 --- a/packages/opencode/src/kilocode/enhance-prompt.ts +++ b/packages/opencode/src/kilocode/enhance-prompt.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import { Provider } from "@/provider/provider" import { LLM } from "@/session/llm" import { Agent } from "@/agent/agent" diff --git a/packages/opencode/src/kilocode/ignore-migrator.ts b/packages/opencode/src/kilocode/ignore-migrator.ts index 2898a94ac9d..9c1a7a8125d 100644 --- a/packages/opencode/src/kilocode/ignore-migrator.ts +++ b/packages/opencode/src/kilocode/ignore-migrator.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import * as path from "path" import os from "os" diff --git a/packages/opencode/src/kilocode/index.ts b/packages/opencode/src/kilocode/index.ts index 261ff142c74..e1a741ca489 100644 --- a/packages/opencode/src/kilocode/index.ts +++ b/packages/opencode/src/kilocode/index.ts @@ -2,6 +2,6 @@ export { ModesMigrator } from "./modes-migrator" export { RulesMigrator } from "./rules-migrator" export { WorkflowsMigrator } from "./workflows-migrator" export { McpMigrator } from "./mcp-migrator" -export { IgnoreMigrator } from "./ignore-migrator" // kilocode_change +export { IgnoreMigrator } from "./ignore-migrator" export { KilocodeConfigInjector } from "./config-injector" export { KilocodePaths } from "./paths" diff --git a/packages/opencode/src/kilocode/modes-migrator.ts b/packages/opencode/src/kilocode/modes-migrator.ts index 8d73cb916b2..1060ec5a08f 100644 --- a/packages/opencode/src/kilocode/modes-migrator.ts +++ b/packages/opencode/src/kilocode/modes-migrator.ts @@ -23,7 +23,6 @@ export namespace ModesMigrator { } // Default modes to skip - these have native Opencode equivalents - // kilocode_change - added "build" for backward compatibility after renaming "build" to "code" const DEFAULT_MODE_SLUGS = new Set(["code", "build", "architect", "ask", "debug", "orchestrator"]) // Group to permission mapping diff --git a/packages/opencode/src/kilocode/project-id.ts b/packages/opencode/src/kilocode/project-id.ts index 0d58c246138..dee8e2e3021 100644 --- a/packages/opencode/src/kilocode/project-id.ts +++ b/packages/opencode/src/kilocode/project-id.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import { Instance } from "@/project/instance" import path from "path" import { $ } from "bun" diff --git a/packages/opencode/src/kilocode/review/command.ts b/packages/opencode/src/kilocode/review/command.ts index 87baa024145..4022aa68272 100644 --- a/packages/opencode/src/kilocode/review/command.ts +++ b/packages/opencode/src/kilocode/review/command.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import type { Command } from "@/command" import { Review } from "./review" diff --git a/packages/opencode/src/kilocode/review/review.ts b/packages/opencode/src/kilocode/review/review.ts index 3bf5072ef4b..4c84fbfa347 100644 --- a/packages/opencode/src/kilocode/review/review.ts +++ b/packages/opencode/src/kilocode/review/review.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import { $ } from "bun" import { Log } from "@/util/log" import { Instance } from "@/project/instance" diff --git a/packages/opencode/src/kilocode/review/types.ts b/packages/opencode/src/kilocode/review/types.ts index f8ad7ff770d..eb4d919148a 100644 --- a/packages/opencode/src/kilocode/review/types.ts +++ b/packages/opencode/src/kilocode/review/types.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import z from "zod" export const DiffHunk = z.object({ diff --git a/packages/opencode/src/kilocode/rules-migrator.ts b/packages/opencode/src/kilocode/rules-migrator.ts index ed5543e0497..49ee235a405 100644 --- a/packages/opencode/src/kilocode/rules-migrator.ts +++ b/packages/opencode/src/kilocode/rules-migrator.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import * as fs from "fs/promises" import * as path from "path" diff --git a/packages/opencode/src/kilocode/workflows-migrator.ts b/packages/opencode/src/kilocode/workflows-migrator.ts index e3151e12c38..c5a709de2be 100644 --- a/packages/opencode/src/kilocode/workflows-migrator.ts +++ b/packages/opencode/src/kilocode/workflows-migrator.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file import * as fs from "fs/promises" import * as path from "path" diff --git a/packages/opencode/src/provider/auth.ts b/packages/opencode/src/provider/auth.ts index 3a712e6ced0..9cf665a801d 100644 --- a/packages/opencode/src/provider/auth.ts +++ b/packages/opencode/src/provider/auth.ts @@ -7,6 +7,8 @@ import type { AuthOuathResult, Hooks } from "@kilocode/plugin" import { NamedError } from "@opencode-ai/util/error" import { Auth } from "@/auth" import { Telemetry } from "@kilocode/kilo-telemetry" // kilocode_change +import { ModelCache } from "./model-cache" // kilocode_change +import { scheduleDisposeAll } from "../kilocode/dispose" // kilocode_change export namespace ProviderAuth { const state = Instance.state(async () => { @@ -121,6 +123,11 @@ export namespace ProviderAuth { Telemetry.trackAuthSuccess(input.providerID) // kilocode_change end + // kilocode_change start - invalidate provider/model cache after auth change + ModelCache.clear(input.providerID) + scheduleDisposeAll() + // kilocode_change end + return } @@ -138,6 +145,10 @@ export namespace ProviderAuth { type: "api", key: input.key, }) + // kilocode_change start - invalidate provider/model cache after auth change + ModelCache.clear(input.providerID) + scheduleDisposeAll() + // kilocode_change end }, ) diff --git a/packages/opencode/src/provider/provider.ts b/packages/opencode/src/provider/provider.ts index f5ed0917631..d7566d924d5 100644 --- a/packages/opencode/src/provider/provider.ts +++ b/packages/opencode/src/provider/provider.ts @@ -1256,7 +1256,7 @@ export namespace Provider { ] // kilocode_change start if (providerID.startsWith("kilo")) { - priority = ["gpt-5-nano"] + priority = ["auto-small"] } // kilocode_change end if (providerID.startsWith("github-copilot")) { @@ -1297,8 +1297,8 @@ export namespace Provider { // kilocode_change start // Check if kilo provider is available before using it const kiloProvider = await state().then((state) => state.providers["kilo"]) - if (kiloProvider && kiloProvider.models["gpt-5-nano"]) { - return getModel("kilo", "gpt-5-nano") + if (kiloProvider && kiloProvider.models["auto-small"]) { + return getModel("kilo", "auto-small") } // kilocode_change end diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index c882207a8ee..a2049a7a39a 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -18,6 +18,8 @@ import { Vcs } from "../project/vcs" import { Agent } from "../agent/agent" import { Skill } from "../skill/skill" import { Auth } from "../auth" +import { ModelCache } from "../provider/model-cache" // kilocode_change +import { scheduleDisposeAll } from "../kilocode/dispose" // kilocode_change import { Flag } from "../flag/flag" import { Command } from "../command" import { Global } from "../global" @@ -167,6 +169,10 @@ export namespace Server { const providerID = c.req.valid("param").providerID const info = c.req.valid("json") await Auth.set(providerID, info) + // kilocode_change start - invalidate provider/model cache after auth change + ModelCache.clear(providerID) + scheduleDisposeAll() + // kilocode_change end return c.json(true) }, ) @@ -197,6 +203,10 @@ export namespace Server { async (c) => { const providerID = c.req.valid("param").providerID await Auth.remove(providerID) + // kilocode_change start - invalidate provider/model cache after auth removal + ModelCache.clear(providerID) + scheduleDisposeAll() + // kilocode_change end return c.json(true) }, ) diff --git a/packages/opencode/test/kilocode/config-injector.test.ts b/packages/opencode/test/kilocode/config-injector.test.ts index 5260e2bc90e..f762eee601f 100644 --- a/packages/opencode/test/kilocode/config-injector.test.ts +++ b/packages/opencode/test/kilocode/config-injector.test.ts @@ -109,7 +109,6 @@ describe("KilocodeConfigInjector", () => { expect(config.command["deploy"]).toBeDefined() }) - // kilocode_change start - Rules migration tests test("includes rules in config", async () => { await using tmp = await tmpdir({ init: async (dir) => { @@ -197,9 +196,7 @@ describe("KilocodeConfigInjector", () => { expect(result.warnings.some((w) => w.includes("Legacy"))).toBe(true) }) - // kilocode_change end - // kilocode_change start - Ignore migration tests test("includes ignore patterns in config", async () => { await using tmp = await tmpdir({ init: async (dir) => { @@ -283,7 +280,6 @@ describe("KilocodeConfigInjector", () => { expect(config.permission.read["*.env"]).toBe("deny") expect(config.permission.read[".env.example"]).toBe("allow") }) - // kilocode_change end }) describe("getEnvVars", () => { diff --git a/packages/opencode/test/kilocode/kilo-gateway-headers.test.ts b/packages/opencode/test/kilocode/kilo-gateway-headers.test.ts index 32050c74bf1..c402e7db8c4 100644 --- a/packages/opencode/test/kilocode/kilo-gateway-headers.test.ts +++ b/packages/opencode/test/kilocode/kilo-gateway-headers.test.ts @@ -1,7 +1,6 @@ -// kilocode_change - new file import { describe, it, expect, afterEach } from "bun:test" import { buildKiloHeaders, getFeatureHeader, getEditorNameHeader } from "@kilocode/kilo-gateway" -import { HEADER_FEATURE, ENV_FEATURE } from "@kilocode/kilo-gateway" +import { HEADER_FEATURE, ENV_FEATURE, ENV_VERSION, DEFAULT_EDITOR_NAME } from "@kilocode/kilo-gateway" describe("getFeatureHeader", () => { const original = process.env[ENV_FEATURE] @@ -30,6 +29,28 @@ describe("getFeatureHeader", () => { }) }) +describe("getEditorNameHeader", () => { + const originalVersion = process.env[ENV_VERSION] + + afterEach(() => { + if (originalVersion === undefined) { + delete process.env[ENV_VERSION] + } else { + process.env[ENV_VERSION] = originalVersion + } + }) + + it("returns default editor name without version when KILOCODE_VERSION is not set", () => { + delete process.env[ENV_VERSION] + expect(getEditorNameHeader()).toBe(DEFAULT_EDITOR_NAME) + }) + + it("appends version when KILOCODE_VERSION is set", () => { + process.env[ENV_VERSION] = "1.2.3" + expect(getEditorNameHeader()).toBe(`${DEFAULT_EDITOR_NAME} 1.2.3`) + }) +}) + describe("buildKiloHeaders", () => { const original = process.env[ENV_FEATURE] diff --git a/packages/opencode/test/kilocode/model-cache-org.test.ts b/packages/opencode/test/kilocode/model-cache-org.test.ts index 9299cfa3ba5..7b70e0c8dfa 100644 --- a/packages/opencode/test/kilocode/model-cache-org.test.ts +++ b/packages/opencode/test/kilocode/model-cache-org.test.ts @@ -1,4 +1,3 @@ -// kilocode_change - new file // Regression test: OAuth accountId must flow into model fetch as kilocodeOrganizationId // When a user logs in via OAuth and selects an enterprise organization, the model fetch // should use the organization-specific endpoint, not the personal endpoint. diff --git a/packages/plugin/package.json b/packages/plugin/package.json index a551758e211..17b195104b9 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/plugin", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "repository": { diff --git a/packages/script/package.json b/packages/script/package.json index 1bc73d38075..35cc1cbd8f8 100644 --- a/packages/script/package.json +++ b/packages/script/package.json @@ -8,7 +8,7 @@ "exports": { ".": "./src/index.ts" }, - "version": "7.0.36", + "version": "7.0.37", "dependencies": {}, "peerDependencies": {} } diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 62b7fdaa81e..44d9ce7c2f0 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/sdk", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "repository": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 138f22ce1e8..63b90fa2ec9 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "7.0.36", + "version": "7.0.37", "type": "module", "license": "MIT", "exports": { diff --git a/packages/util/package.json b/packages/util/package.json index 7063db14cbf..610d32f428e 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "7.0.36", + "version": "7.0.37", "private": true, "type": "module", "license": "MIT", diff --git a/script/upstream/package.json b/script/upstream/package.json index 2c20177c00c..524b82ee9cc 100644 --- a/script/upstream/package.json +++ b/script/upstream/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/upstream-merge", - "version": "7.0.36", + "version": "7.0.37", "private": true, "type": "module", "description": "Scripts for automating upstream opencode merges into Kilo", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 053c86a9234..efdaf05c2b8 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "7.0.36", + "version": "7.0.37", "publisher": "sst-dev", "repository": { "type": "git",