diff --git a/.changeset/jetbrains-active-badges.md b/.changeset/jetbrains-active-badges.md deleted file mode 100644 index 89e19d5f707..00000000000 --- a/.changeset/jetbrains-active-badges.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Show question, permission, plan, and login-required badges for active JetBrains sessions in recent and history lists. diff --git a/.changeset/jetbrains-auto-approve.md b/.changeset/jetbrains-auto-approve.md deleted file mode 100644 index fbedb802c55..00000000000 --- a/.changeset/jetbrains-auto-approve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": minor ---- - -Support toggling auto-approve for permission prompts from the JetBrains chat input. diff --git a/.changeset/jetbrains-history-refresh.md b/.changeset/jetbrains-history-refresh.md deleted file mode 100644 index bf87fff84ec..00000000000 --- a/.changeset/jetbrains-history-refresh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Refresh JetBrains history and recent-session rows when active session titles change, and keep pending inactive sessions alive when switching views. diff --git a/.changeset/jetbrains-question-scroll-overlay.md b/.changeset/jetbrains-question-scroll-overlay.md deleted file mode 100644 index ae3d2a9633f..00000000000 --- a/.changeset/jetbrains-question-scroll-overlay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Show a question indicator on the JetBrains session scroll overlay when user input is needed. diff --git a/.changeset/jetbrains-resizing-prompt.md b/.changeset/jetbrains-resizing-prompt.md deleted file mode 100644 index 858eccf6a96..00000000000 --- a/.changeset/jetbrains-resizing-prompt.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Resize the JetBrains prompt editor as prompt lines are added or removed. diff --git a/.changeset/jetbrains-session-hover.md b/.changeset/jetbrains-session-hover.md deleted file mode 100644 index 181ad76ac4a..00000000000 --- a/.changeset/jetbrains-session-hover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Refine JetBrains session transcript styling with subtler tool rows, prompt-styled user messages, and underlined read file links that open files in the IDE. diff --git a/.changeset/jetbrains-session-links.md b/.changeset/jetbrains-session-links.md deleted file mode 100644 index 63de324a815..00000000000 --- a/.changeset/jetbrains-session-links.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Support opening links in JetBrains session markdown transcripts. diff --git a/.changeset/jetbrains-session-scroll.md b/.changeset/jetbrains-session-scroll.md deleted file mode 100644 index d91e0ec1f90..00000000000 --- a/.changeset/jetbrains-session-scroll.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Keep JetBrains chat scrolled to the latest prompt and question updates when following the bottom. diff --git a/.changeset/mercury-next-edit.md b/.changeset/mercury-next-edit.md deleted file mode 100644 index 976b7990df4..00000000000 --- a/.changeset/mercury-next-edit.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": minor ---- - -Add Mercury Next Edit as an opt-in autocomplete mode. Predicts multi-line edits beyond the cursor (including off-cursor and pure-insertion edits) and surfaces them with a Tab-to-jump / Tab-to-apply affordance. Select "Mercury Next Edit" under the autocomplete model setting to enable it (requires an Inception API key). Thanks [@tfiras](https://github.com/tfiras)! diff --git a/.changeset/polite-errors-glow.md b/.changeset/polite-errors-glow.md new file mode 100644 index 00000000000..bc37608e936 --- /dev/null +++ b/.changeset/polite-errors-glow.md @@ -0,0 +1,6 @@ +--- +"@kilocode/kilo-ui": patch +"kilo-code": patch +--- + +Improve chat error styling in the VS Code extension. diff --git a/.changeset/quiet-agents-launch.md b/.changeset/quiet-agents-launch.md deleted file mode 100644 index 0fed5274876..00000000000 --- a/.changeset/quiet-agents-launch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"kilo-code": minor ---- - -Make the Agent Manager tool available by default in VS Code. diff --git a/.changeset/witty-cabin.md b/.changeset/witty-cabin.md deleted file mode 100644 index 47dbc193d64..00000000000 --- a/.changeset/witty-cabin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@kilocode/kilo-jetbrains": patch ---- - -Show running badges on active sessions in JetBrains recent and history lists. diff --git a/.github/workflows/check-opencode-annotations.yml b/.github/workflows/check-opencode-annotations.yml index 514958ad494..e30997d8483 100644 --- a/.github/workflows/check-opencode-annotations.yml +++ b/.github/workflows/check-opencode-annotations.yml @@ -38,6 +38,9 @@ jobs: fi # kilocode_change start + - name: Check Effect Promise facade allowlist + run: bun run script/check-opencode-promise-facades.ts + - name: Check workflow allowlist run: bun run script/check-workflows.ts # kilocode_change end diff --git a/.github/workflows/smoke-test.yml b/.github/workflows/smoke-test.yml index b0604eb8ebc..55f29db1a98 100644 --- a/.github/workflows/smoke-test.yml +++ b/.github/workflows/smoke-test.yml @@ -125,7 +125,7 @@ jobs: ./scripts/run_eval.sh \ -m kilo/anthropic/claude-sonnet-4.6 \ -d terminal-bench-sample \ - -t "log-summary-date-ranges" \ + --include-task-name "log-summary-date-ranges" \ --job-name smoke-test-log-summary \ --timeout-multiplier 2 diff --git a/AGENTS.md b/AGENTS.md index 914d394946b..fa8cfc3b7a3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,6 +21,7 @@ Kilo CLI is an open source AI coding agent that generates code from natural lang - **Source links**: After adding or changing URLs in `packages/kilo-vscode/`, `packages/kilo-vscode/webview-ui/`, or `packages/opencode/src/`, run `bun run script/extract-source-links.ts` from the repo root and commit the updated `packages/kilo-docs/source-links.md`. CI runs this check — the build fails if the file is stale. - **kilocode_change check**: `bun run check-kilocode-change` from `packages/kilo-vscode/`. CI runs this — `kilocode_change` is a marker for upstream merge conflicts and must not appear in `packages/kilo-vscode/` or `packages/kilo-ui/` (these are entirely Kilo Code additions). Remove the markers before pushing. - **opencode annotation check**: `bun run script/check-opencode-annotations.ts` from repo root. CI runs this on PRs touching `packages/opencode/` — every Kilo-specific change in shared opencode files must be annotated with `kilocode_change` markers. Exempt paths (no markers needed): `packages/opencode/src/kilocode/`, `packages/opencode/test/kilocode/`, and any path containing `kilocode` in the name. +- **Effect facade ratchet**: Do not add runtime-backed Promise facades to shared `packages/opencode/src` Effect services; use service dependencies, `AppRuntime`, or Kilo-owned boundaries. Run `bun run script/check-opencode-promise-facades.ts` when touching service adapters. - **workflow allowlist**: `bun run script/check-workflows.ts` from repo root. CI runs this as part of the annotations workflow — any `.yml` / `.yaml` file added to or removed from `.github/workflows/` must be reflected in the hardcoded list in `script/check-workflows.ts`. Prevents upstream-merged workflows from silently starting to run in our CI. - **Backend/SDK programmatic testing**: see [TESTING.md](./TESTING.md) for spawning the local main-branch backend (`bun dev serve`) and driving it via `curl` — use this instead of `kilo serve` (prod binary) when testing backend fixes. @@ -84,23 +85,7 @@ Turborepo + Bun workspaces. The packages you'll work with most: ### Avoid let statements -We don't like `let` statements, especially combined with if/else statements. -Prefer `const`. - -Good: - -```ts -const foo = condition ? 1 : 2 -``` - -Bad: - -```ts -let foo - -if (condition) foo = 1 -else foo = 2 -``` +Prefer `const`. Replace `let` + if/else assignment with a ternary or an IIFE. Reassignment is the only legitimate reason to reach for `let`. ### Naming Enforcement (Read This) @@ -115,25 +100,7 @@ THIS RULE IS MANDATORY FOR AGENT WRITTEN CODE. ### Avoid else statements -Prefer early returns or using an `iife` to avoid else statements. - -Good: - -```ts -function foo() { - if (condition) return 1 - return 2 -} -``` - -Bad: - -```ts -function foo() { - if (condition) return 1 - else return 2 -} -``` +Prefer early returns (or an IIFE) over `else`. After an `if` that returns/throws, the `else` is redundant. ### No empty catch blocks @@ -141,46 +108,11 @@ Never leave a `catch` block empty. An empty `catch` silently swallows errors and 1. Is the `try`/`catch` even needed? (prefer removing it) 2. Should the error be handled explicitly? (recover, retry, rethrow) -3. At minimum, log it so failures are visible - -Good: - -```ts -try { - await save(data) -} catch (err) { - log.error("save failed", { err }) -} -``` - -Bad: - -```ts -try { - await save(data) -} catch {} -``` +3. At minimum, log it via `log.error("...", { err })` so failures are visible — never `catch {}` or `catch (e) {}` with no body. ### Prefer single word naming -Try your best to find a single word name for your variables, functions, etc. -Only use multiple words if you cannot. - -Good: - -```ts -const foo = 1 -const bar = 2 -const baz = 3 -``` - -Bad: - -```ts -const fooBar = 1 -const barBaz = 2 -const bazFoo = 3 -``` +Default to a single-word name for variables, parameters, and helper functions. Reach for a multi-word name only when a single word would be genuinely ambiguous in context — not just because the longer name "reads nicer". The rule is about meaning, not character count: don't introduce camelCase compounds like `inputPID`, `existingClient`, `connectTimeout`, or `workerPath` when `pid`, `client`, `timeout`, or `path` is already clear from the surrounding code. See the "Naming Enforcement" section above for the preferred vocabulary. ## Testing @@ -219,7 +151,7 @@ Changeset descriptions appear directly in release notes and are read by end user ## Pull Requests -PR descriptions should be 2-3 lines covering **what** changed and **why**. Focus on intent and context a reviewer can't get from the diff — skip file-by-file inventories, test result summaries, and anything obvious from the code itself. +PR descriptions should explain **what** changed, **why** the change is needed, and the intent or constraints a reviewer cannot infer from the diff alone. Keep simple PRs brief, but give non-trivial changes enough context to stand on their own. Skip file-by-file inventories, test result summaries, and anything obvious from the code itself. ## GitHub Issues diff --git a/bun.lock b/bun.lock index a5bfc77347b..9efdf397bd2 100644 --- a/bun.lock +++ b/bun.lock @@ -33,7 +33,7 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "7.3.12", + "version": "7.3.14", "bin": { "opencode": "./bin/opencode", }, @@ -68,7 +68,7 @@ }, "packages/kilo-docs": { "name": "@kilocode/kilo-docs", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@docsearch/css": "^4", "@docsearch/js": "^4", @@ -98,7 +98,7 @@ }, "packages/kilo-gateway": { "name": "@kilocode/kilo-gateway", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@ai-sdk/alibaba": "1.0.17", "@ai-sdk/anthropic": "3.0.71", @@ -113,8 +113,8 @@ "zod": "catalog:", }, "devDependencies": { - "@opentui/core": "0.1.75", - "@opentui/solid": "0.1.75", + "@opentui/core": "catalog:", + "@opentui/solid": "catalog:", "@tsconfig/node22": "catalog:", "@types/node": "catalog:", "@typescript/native-preview": "catalog:", @@ -134,7 +134,7 @@ }, "packages/kilo-i18n": { "name": "@kilocode/kilo-i18n", - "version": "7.3.12", + "version": "7.3.14", "devDependencies": { "@tsconfig/node22": "catalog:", "@types/bun": "catalog:", @@ -144,7 +144,7 @@ }, "packages/kilo-indexing": { "name": "@kilocode/kilo-indexing", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@aws-sdk/client-bedrock-runtime": "3.1005.0", "@aws-sdk/credential-provider-ini": "3.972.31", @@ -176,11 +176,11 @@ }, "packages/kilo-jetbrains": { "name": "@kilocode/kilo-jetbrains", - "version": "7.3.12", + "version": "7.3.14", }, "packages/kilo-telemetry": { "name": "@kilocode/kilo-telemetry", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@kilocode/kilo-gateway": "workspace:*", "posthog-node": "4.4.0", @@ -194,7 +194,7 @@ }, "packages/kilo-ui": { "name": "@kilocode/kilo-ui", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "0.13.11", @@ -231,7 +231,7 @@ }, "packages/kilo-vscode": { "name": "kilo-code", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@anthropic-ai/sdk": "^0.39.0", "@kilocode/kilo-gateway": "workspace:*", @@ -294,7 +294,7 @@ }, "packages/opencode": { "name": "@kilocode/cli", - "version": "7.3.12", + "version": "7.3.14", "bin": { "kilo": "./bin/kilo", "kilocode": "./bin/kilo", @@ -452,7 +452,7 @@ }, "packages/plugin": { "name": "@kilocode/plugin", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@kilocode/sdk": "workspace:*", "effect": "catalog:", @@ -477,7 +477,7 @@ }, "packages/script": { "name": "@opencode-ai/script", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "semver": "^7.6.3", }, @@ -488,7 +488,7 @@ }, "packages/sdk/js": { "name": "@kilocode/sdk", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "cross-spawn": "catalog:", }, @@ -503,7 +503,7 @@ }, "packages/storybook": { "name": "@opencode-ai/storybook", - "version": "7.3.12", + "version": "7.3.14", "devDependencies": { "@opencode-ai/ui": "workspace:*", "@solidjs/meta": "catalog:", @@ -526,7 +526,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "7.3.12", + "version": "7.3.14", "dependencies": { "@kilocode/sdk": "workspace:*", "@kobalte/core": "catalog:", @@ -589,6 +589,8 @@ }, "overrides": { "@effect/platform-node-shared": "4.0.0-beta.46", + "@opentui/core": "catalog:", + "@opentui/solid": "catalog:", "@types/bun": "catalog:", "@types/node": "catalog:", "@xmldom/xmldom": ">=0.8.12", @@ -602,6 +604,7 @@ "path-to-regexp": ">=8.4.0", "picomatch": ">=2.3.2", "smol-toml": ">=1.6.1", + "solid-js": "catalog:", }, "catalog": { "@cloudflare/workers-types": "4.20251008.0", @@ -985,8 +988,6 @@ "@corvu/utils": ["@corvu/utils@0.4.2", "", { "dependencies": { "@floating-ui/dom": "^1.6.11" }, "peerDependencies": { "solid-js": "^1.8" } }, "sha512-Ox2kYyxy7NoXdKWdHeDEjZxClwzO4SKM8plAaVwmAJPxHMqA0rLOoAsa+hBDwRLpctf+ZRnAd/ykguuJidnaTA=="], - "@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="], - "@docsearch/css": ["@docsearch/css@4.6.2", "", {}, "sha512-fH/cn8BjEEdM2nJdjNMHIvOVYupG6AIDtFVDgIZrNzdCSj4KXr9kd+hsehqsNGYjpUjObeKYKvgy/IwCb1jZYQ=="], "@docsearch/js": ["@docsearch/js@4.6.2", "", {}, "sha512-qj1yoxl3y4GKoK7+VM6fq/rQqPnvUmg3IKzJ9x0VzN14QVzdB/SG/J6VfV1BWT5RcPUFxIcVwoY1fwHM2fSRRw=="], @@ -1203,62 +1204,6 @@ "@istanbuljs/schema": ["@istanbuljs/schema@0.1.6", "", {}, "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw=="], - "@jimp/core": ["@jimp/core@1.6.0", "", { "dependencies": { "@jimp/file-ops": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "await-to-js": "^3.0.0", "exif-parser": "^0.1.12", "file-type": "^16.0.0", "mime": "3" } }, "sha512-EQQlKU3s9QfdJqiSrZWNTxBs3rKXgO2W+GxNXDtwchF3a4IqxDheFX1ti+Env9hdJXDiYLp2jTRjlxhPthsk8w=="], - - "@jimp/diff": ["@jimp/diff@1.6.0", "", { "dependencies": { "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "pixelmatch": "^5.3.0" } }, "sha512-+yUAQ5gvRC5D1WHYxjBHZI7JBRusGGSLf8AmPRPCenTzh4PA+wZ1xv2+cYqQwTfQHU5tXYOhA0xDytfHUf1Zyw=="], - - "@jimp/file-ops": ["@jimp/file-ops@1.6.0", "", {}, "sha512-Dx/bVDmgnRe1AlniRpCKrGRm5YvGmUwbDzt+MAkgmLGf+jvBT75hmMEZ003n9HQI/aPnm/YKnXjg/hOpzNCpHQ=="], - - "@jimp/js-bmp": ["@jimp/js-bmp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "bmp-ts": "^1.0.9" } }, "sha512-FU6Q5PC/e3yzLyBDXupR3SnL3htU7S3KEs4e6rjDP6gNEOXRFsWs6YD3hXuXd50jd8ummy+q2WSwuGkr8wi+Gw=="], - - "@jimp/js-gif": ["@jimp/js-gif@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "gifwrap": "^0.10.1", "omggif": "^1.0.10" } }, "sha512-N9CZPHOrJTsAUoWkWZstLPpwT5AwJ0wge+47+ix3++SdSL/H2QzyMqxbcDYNFe4MoI5MIhATfb0/dl/wmX221g=="], - - "@jimp/js-jpeg": ["@jimp/js-jpeg@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "jpeg-js": "^0.4.4" } }, "sha512-6vgFDqeusblf5Pok6B2DUiMXplH8RhIKAryj1yn+007SIAQ0khM1Uptxmpku/0MfbClx2r7pnJv9gWpAEJdMVA=="], - - "@jimp/js-png": ["@jimp/js-png@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "pngjs": "^7.0.0" } }, "sha512-AbQHScy3hDDgMRNfG0tPjL88AV6qKAILGReIa3ATpW5QFjBKpisvUaOqhzJ7Reic1oawx3Riyv152gaPfqsBVg=="], - - "@jimp/js-tiff": ["@jimp/js-tiff@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "utif2": "^4.1.0" } }, "sha512-zhReR8/7KO+adijj3h0ZQUOiun3mXUv79zYEAKvE0O+rP7EhgtKvWJOZfRzdZSNv0Pu1rKtgM72qgtwe2tFvyw=="], - - "@jimp/plugin-blit": ["@jimp/plugin-blit@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M+uRWl1csi7qilnSK8uxK4RJMSuVeBiO1AY0+7APnfUbQNZm6hCe0CCFv1Iyw1D/Dhb8ph8fQgm5mwM0eSxgVA=="], - - "@jimp/plugin-blur": ["@jimp/plugin-blur@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-zrM7iic1OTwUCb0g/rN5y+UnmdEsT3IfuCXCJJNs8SZzP0MkZ1eTvuwK9ZidCuMo4+J3xkzCidRwYXB5CyGZTw=="], - - "@jimp/plugin-circle": ["@jimp/plugin-circle@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-xt1Gp+LtdMKAXfDp3HNaG30SPZW6AQ7dtAtTnoRKorRi+5yCJjKqXRgkewS5bvj8DEh87Ko1ydJfzqS3P2tdWw=="], - - "@jimp/plugin-color": ["@jimp/plugin-color@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "tinycolor2": "^1.6.0", "zod": "^3.23.8" } }, "sha512-J5q8IVCpkBsxIXM+45XOXTrsyfblyMZg3a9eAo0P7VPH4+CrvyNQwaYatbAIamSIN1YzxmO3DkIZXzRjFSz1SA=="], - - "@jimp/plugin-contain": ["@jimp/plugin-contain@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-oN/n+Vdq/Qg9bB4yOBOxtY9IPAtEfES8J1n9Ddx+XhGBYT1/QTU/JYkGaAkIGoPnyYvmLEDqMz2SGihqlpqfzQ=="], - - "@jimp/plugin-cover": ["@jimp/plugin-cover@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Iow0h6yqSC269YUJ8HC3Q/MpCi2V55sMlbkkTTx4zPvd8mWZlC0ykrNDeAy9IJegrQ7v5E99rJwmQu25lygKLA=="], - - "@jimp/plugin-crop": ["@jimp/plugin-crop@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-KqZkEhvs+21USdySCUDI+GFa393eDIzbi1smBqkUPTE+pRwSWMAf01D5OC3ZWB+xZsNla93BDS9iCkLHA8wang=="], - - "@jimp/plugin-displace": ["@jimp/plugin-displace@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-4Y10X9qwr5F+Bo5ME356XSACEF55485j5nGdiyJ9hYzjQP9nGgxNJaZ4SAOqpd+k5sFaIeD7SQ0Occ26uIng5Q=="], - - "@jimp/plugin-dither": ["@jimp/plugin-dither@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0" } }, "sha512-600d1RxY0pKwgyU0tgMahLNKsqEcxGdbgXadCiVCoGd6V6glyCvkNrnnwC0n5aJ56Htkj88PToSdF88tNVZEEQ=="], - - "@jimp/plugin-fisheye": ["@jimp/plugin-fisheye@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-E5QHKWSCBFtpgZarlmN3Q6+rTQxjirFqo44ohoTjzYVrDI6B6beXNnPIThJgPr0Y9GwfzgyarKvQuQuqCnnfbA=="], - - "@jimp/plugin-flip": ["@jimp/plugin-flip@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-/+rJVDuBIVOgwoyVkBjUFHtP+wmW0r+r5OQ2GpatQofToPVbJw1DdYWXlwviSx7hvixTWLKVgRWQ5Dw862emDg=="], - - "@jimp/plugin-hash": ["@jimp/plugin-hash@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "any-base": "^1.1.0" } }, "sha512-wWzl0kTpDJgYVbZdajTf+4NBSKvmI3bRI8q6EH9CVeIHps9VWVsUvEyb7rpbcwVLWYuzDtP2R0lTT6WeBNQH9Q=="], - - "@jimp/plugin-mask": ["@jimp/plugin-mask@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-Cwy7ExSJMZszvkad8NV8o/Z92X2kFUFM8mcDAhNVxU0Q6tA0op2UKRJY51eoK8r6eds/qak3FQkXakvNabdLnA=="], - - "@jimp/plugin-print": ["@jimp/plugin-print@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/types": "1.6.0", "parse-bmfont-ascii": "^1.0.6", "parse-bmfont-binary": "^1.0.6", "parse-bmfont-xml": "^1.1.6", "simple-xml-to-json": "^1.2.2", "zod": "^3.23.8" } }, "sha512-zarTIJi8fjoGMSI/M3Xh5yY9T65p03XJmPsuNet19K/Q7mwRU6EV2pfj+28++2PV2NJ+htDF5uecAlnGyxFN2A=="], - - "@jimp/plugin-quantize": ["@jimp/plugin-quantize@1.6.0", "", { "dependencies": { "image-q": "^4.0.0", "zod": "^3.23.8" } }, "sha512-EmzZ/s9StYQwbpG6rUGBCisc3f64JIhSH+ncTJd+iFGtGo0YvSeMdAd+zqgiHpfZoOL54dNavZNjF4otK+mvlg=="], - - "@jimp/plugin-resize": ["@jimp/plugin-resize@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/types": "1.6.0", "zod": "^3.23.8" } }, "sha512-uSUD1mqXN9i1SGSz5ov3keRZ7S9L32/mAQG08wUwZiEi5FpbV0K8A8l1zkazAIZi9IJzLlTauRNU41Mi8IF9fA=="], - - "@jimp/plugin-rotate": ["@jimp/plugin-rotate@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-JagdjBLnUZGSG4xjCLkIpQOZZ3Mjbg8aGCCi4G69qR+OjNpOeGI7N2EQlfK/WE8BEHOW5vdjSyglNqcYbQBWRw=="], - - "@jimp/plugin-threshold": ["@jimp/plugin-threshold@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0", "zod": "^3.23.8" } }, "sha512-M59m5dzLoHOVWdM41O8z9SyySzcDn43xHseOH0HavjsfQsT56GGCC4QzU1banJidbUrePhzoEdS42uFE8Fei8w=="], - - "@jimp/types": ["@jimp/types@1.6.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-7UfRsiKo5GZTAATxm2qQ7jqmUXP0DxTArztllTcYdyw6Xi5oT4RaoXynVtCD4UyLK5gJgkZJcwonoijrhYFKfg=="], - - "@jimp/utils": ["@jimp/utils@1.6.0", "", { "dependencies": { "@jimp/types": "1.6.0", "tinycolor2": "^1.6.0" } }, "sha512-gqFTGEosKbOkYF/WFj26jMHOI5OH2jeP1MmC/zbK6BF6VJBf8rIC5898dPfSzZEbSA0wbbV5slbntWVc5PKLFA=="], - "@joshwooding/vite-plugin-react-docgen-typescript": ["@joshwooding/vite-plugin-react-docgen-typescript@0.6.4", "", { "dependencies": { "glob": "^13.0.1", "react-docgen-typescript": "^2.2.2" }, "peerDependencies": { "typescript": ">= 4.3.x", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["typescript"] }, "sha512-6PyZBYKnnVNqOSB0YFly+62R7dmov8segT27A+RVTBVd4iAE6kbW9QBJGlyR2yG4D4ohzhZSTIu7BK1UTtmFFA=="], "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="], @@ -2017,8 +1962,6 @@ "@thisbeyond/solid-dnd": ["@thisbeyond/solid-dnd@0.7.5", "", { "peerDependencies": { "solid-js": "^1.5" } }, "sha512-DfI5ff+yYGpK9M21LhYwIPlbP2msKxN2ARwuu6GF8tT1GgNVDTI8VCQvH4TJFoVApP9d44izmAcTh/iTCH2UUw=="], - "@tokenizer/token": ["@tokenizer/token@0.3.0", "", {}, "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A=="], - "@ts-morph/common": ["@ts-morph/common@0.28.1", "", { "dependencies": { "minimatch": "^10.0.1", "path-browserify": "^1.0.1", "tinyglobby": "^0.2.14" } }, "sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g=="], "@tsconfig/bun": ["@tsconfig/bun@1.0.9", "", {}, "sha512-4M0/Ivfwcpz325z6CwSifOBZYji3DFOEpY6zEUt0+Xi2qRhzwvmqQN9XAHJh3OVvRJuAqVTLU2abdCplvp6mwQ=="], @@ -2311,8 +2254,6 @@ "@webcontainer/env": ["@webcontainer/env@1.1.1", "", {}, "sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng=="], - "@webgpu/types": ["@webgpu/types@0.1.69", "", {}, "sha512-RPmm6kgRbI8e98zSD3RVACvnuktIja5+yLgDAkTmxLr90BEwdTXRQWNLF3ETTTyH/8mKhznZuN5AveXYFEsMGQ=="], - "@xterm/addon-clipboard": ["@xterm/addon-clipboard@0.2.0", "", { "dependencies": { "js-base64": "^3.7.5" } }, "sha512-Dl31BCtBhLaUEECUbEiVcCLvLBbaeGYdT7NofB8OJkGTD3MWgBsaLjXvfGAD4tQNHhm6mbKyYkR7XD8kiZsdNg=="], "@xterm/addon-fit": ["@xterm/addon-fit@0.11.0", "", {}, "sha512-jYcgT6xtVYhnhgxh3QgYDnnNMYTcf8ElbxxFzX0IZo+vabQqSPAjC3c1wJrKB5E19VwQei89QCiZZP86DCPF7g=="], @@ -2365,8 +2306,6 @@ "ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="], - "any-base": ["any-base@1.1.0", "", {}, "sha512-uMgjozySS8adZZYePpaWs8cxB9/kdzmpX6SgJZ+wbz1K5eYk5QMYDVJaZKhxyIHUdnnJkfR7SVgStgH7LkGUyg=="], - "anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="], "apache-arrow": ["apache-arrow@18.1.0", "", { "dependencies": { "@swc/helpers": "^0.5.11", "@types/command-line-args": "^5.2.3", "@types/command-line-usage": "^5.0.4", "@types/node": "^20.13.0", "command-line-args": "^5.2.1", "command-line-usage": "^7.0.1", "flatbuffers": "^24.3.25", "json-bignum": "^0.0.3", "tslib": "^2.6.2" }, "bin": { "arrow2csv": "bin/arrow2csv.js" } }, "sha512-v/ShMp57iBnBp4lDgV8Jx3d3Q5/Hac25FWmQ98eMahUiHPXcvwIMKJD0hBIgclm/FCG+LwPkAKtkRO1O/W0YGg=="], @@ -2417,8 +2356,6 @@ "avvio": ["avvio@9.2.0", "", { "dependencies": { "@fastify/error": "^4.0.0", "fastq": "^1.17.1" } }, "sha512-2t/sy01ArdHHE0vRH5Hsay+RtCZt3dLPji7W7/MMOCEgze5b7SNDC4j5H6FnVgPkI1MTNFGzHdHrVXDDl7QSSQ=="], - "await-to-js": ["await-to-js@3.0.0", "", {}, "sha512-zJAaP9zxTcvTHRlejau3ZOY4V7SRpiByf3/dxx2uyKxxor19tpmpV2QRsTKikckwhaPmr2dVpxxMr7jOCYVp5g=="], - "aws-sdk": ["aws-sdk@2.1692.0", "", { "dependencies": { "buffer": "4.9.2", "events": "1.1.1", "ieee754": "1.1.13", "jmespath": "0.16.0", "querystring": "0.2.0", "sax": "1.2.1", "url": "0.10.3", "util": "^0.12.4", "uuid": "8.0.0", "xml2js": "0.6.2" } }, "sha512-x511uiJ/57FIsbgUe5csJ13k3uzu25uWQE+XqfBis/sB0SFoiElJWXRkgEAUh0U6n40eT3ay5Ue4oPkRMu1LYw=="], "aws4fetch": ["aws4fetch@1.0.18", "", {}, "sha512-3Cf+YaUl07p24MoQ46rFwulAmiyCwH2+1zw1ZyPAX5OtJ34Hh185DwB8y/qRLb6cYYYtSFJ9pthyLc0MD4e8sQ=="], @@ -2473,8 +2410,6 @@ "blueimp-md5": ["blueimp-md5@2.19.0", "", {}, "sha512-DRQrD6gJyy8FbiE4s+bDoXS9hiW3Vbx5uCdwvcCf3zLHL+Iv7LtGHLpr+GZV8rHG8tK766FGYBwRbu8pELTt+w=="], - "bmp-ts": ["bmp-ts@1.0.9", "", {}, "sha512-cTEHk2jLrPyi+12M3dhpEbnnPOsaZuq7C45ylbbQIiWgDFZq4UVYPEY5mlqjvsj/6gJv9qX5sa+ebDzLXT28Vw=="], - "body-parser": ["body-parser@2.2.2", "", { "dependencies": { "bytes": "^3.1.2", "content-type": "^1.0.5", "debug": "^4.4.3", "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" } }, "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA=="], "bonjour-service": ["bonjour-service@1.3.0", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "multicast-dns": "^7.2.5" } }, "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA=="], @@ -2509,16 +2444,6 @@ "bun-types": ["bun-types@1.3.12", "", { "dependencies": { "@types/node": "*" } }, "sha512-HqOLj5PoFajAQciOMRiIZGNoKxDJSr6qigAttOX40vJuSp6DN/CxWp9s3C1Xwm4oH7ybueITwiaOcWXoYVoRkA=="], - "bun-webgpu": ["bun-webgpu@0.1.4", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.4", "bun-webgpu-darwin-x64": "^0.1.4", "bun-webgpu-linux-x64": "^0.1.4", "bun-webgpu-win32-x64": "^0.1.4" } }, "sha512-Kw+HoXl1PMWJTh9wvh63SSRofTA8vYBFCw0XEP1V1fFdQEDhI8Sgf73sdndE/oDpN/7CMx0Yv/q8FCvO39ROMQ=="], - - "bun-webgpu-darwin-arm64": ["bun-webgpu-darwin-arm64@0.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-lIsDkPzJzPl6yrB5CUOINJFPnTRv6fF/Q8J1mAr43ogSp86WZEg9XZKaT6f3EUJ+9ETogGoMnoj1q0AwHUTbAQ=="], - - "bun-webgpu-darwin-x64": ["bun-webgpu-darwin-x64@0.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-uEddf5U7GvKIkM/BV18rUKtYHL6d0KeqBjNHwfqDH9QgEo9KVSKvJXS5I/sMefk5V5pIYE+8tQhtrREevhocng=="], - - "bun-webgpu-linux-x64": ["bun-webgpu-linux-x64@0.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-Y/f15j9r8ba0xUz+3lATtS74OE+PPzQXO7Do/1eCluJcuOlfa77kMjvBK/ShWnem3Y9xqi59pebTPOGRB+CaJA=="], - - "bun-webgpu-win32-x64": ["bun-webgpu-win32-x64@0.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-MHSFAKqizISb+C5NfDrFe3g0Al5Njnu0j/A+oO2Q+bIWX+fUYjBSowiYE1ZXJx65KuryuB+tiM7Qh6cQbVvkEg=="], - "bundle-name": ["bundle-name@4.1.0", "", { "dependencies": { "run-applescript": "^7.0.0" } }, "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q=="], "bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="], @@ -2933,8 +2858,6 @@ "execa": ["execa@8.0.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^8.0.1", "human-signals": "^5.0.0", "is-stream": "^3.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^5.1.0", "onetime": "^6.0.0", "signal-exit": "^4.1.0", "strip-final-newline": "^3.0.0" } }, "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg=="], - "exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="], - "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="], "expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="], @@ -3003,8 +2926,6 @@ "file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="], - "file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="], - "fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="], "finalhandler": ["finalhandler@2.1.1", "", { "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "on-finished": "^2.4.1", "parseurl": "^1.3.3", "statuses": "^2.0.1" } }, "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA=="], @@ -3089,8 +3010,6 @@ "get-tsconfig": ["get-tsconfig@4.14.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA=="], - "gifwrap": ["gifwrap@0.10.1", "", { "dependencies": { "image-q": "^4.0.0", "omggif": "^1.0.10" } }, "sha512-2760b1vpJHNmLzZ/ubTtNnEx5WApN/PYWJvXvgS+tL1egTTthayFYIQQNi136FLEDcN/IyEY2EcGpIITD6eYUw=="], - "giget": ["giget@2.0.0", "", { "dependencies": { "citty": "^0.1.6", "consola": "^3.4.0", "defu": "^6.1.4", "node-fetch-native": "^1.6.6", "nypm": "^0.6.0", "pathe": "^2.0.3" }, "bin": { "giget": "dist/cli.mjs" } }, "sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA=="], "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="], @@ -3181,8 +3100,6 @@ "ignore-walk": ["ignore-walk@8.0.0", "", { "dependencies": { "minimatch": "^10.0.3" } }, "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A=="], - "image-q": ["image-q@4.0.0", "", { "dependencies": { "@types/node": "16.9.1" } }, "sha512-PfJGVgIfKQJuq3s0tTDOKtztksibuUEbJQIYT3by6wctQo+Rdlh7ef4evJ5NCdxY4CfMbvFkocEwbl4BF8RlJw=="], - "immediate": ["immediate@3.0.6", "", {}, "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ=="], "immer": ["immer@11.1.4", "", {}, "sha512-XREFCPo6ksxVzP4E0ekD5aMdf8WMwmdNaz6vuvxgI40UaEiu6q3p8X52aU6GdyvLY3XXX/8R7JOTXStz/nBbRw=="], @@ -3283,16 +3200,12 @@ "jackspeak": ["jackspeak@4.2.3", "", { "dependencies": { "@isaacs/cliui": "^9.0.0" } }, "sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg=="], - "jimp": ["jimp@1.6.0", "", { "dependencies": { "@jimp/core": "1.6.0", "@jimp/diff": "1.6.0", "@jimp/js-bmp": "1.6.0", "@jimp/js-gif": "1.6.0", "@jimp/js-jpeg": "1.6.0", "@jimp/js-png": "1.6.0", "@jimp/js-tiff": "1.6.0", "@jimp/plugin-blit": "1.6.0", "@jimp/plugin-blur": "1.6.0", "@jimp/plugin-circle": "1.6.0", "@jimp/plugin-color": "1.6.0", "@jimp/plugin-contain": "1.6.0", "@jimp/plugin-cover": "1.6.0", "@jimp/plugin-crop": "1.6.0", "@jimp/plugin-displace": "1.6.0", "@jimp/plugin-dither": "1.6.0", "@jimp/plugin-fisheye": "1.6.0", "@jimp/plugin-flip": "1.6.0", "@jimp/plugin-hash": "1.6.0", "@jimp/plugin-mask": "1.6.0", "@jimp/plugin-print": "1.6.0", "@jimp/plugin-quantize": "1.6.0", "@jimp/plugin-resize": "1.6.0", "@jimp/plugin-rotate": "1.6.0", "@jimp/plugin-threshold": "1.6.0", "@jimp/types": "1.6.0", "@jimp/utils": "1.6.0" } }, "sha512-YcwCHw1kiqEeI5xRpDlPPBGL2EOpBKLwO4yIBJcXWHPj5PnA5urGq0jbyhM5KoNpypQ6VboSoxc9D8HyfvngSg=="], - "jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="], "jmespath": ["jmespath@0.16.0", "", {}, "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw=="], "jose": ["jose@5.2.3", "", {}, "sha512-KUXdbctm1uHVL8BYhnyHkgp3zDX5KW8ZhAKVFEfUbU2P8Alpzjb+48hHvjOdQIyPshoblhzsuqOwEEAbtHVirA=="], - "jpeg-js": ["jpeg-js@0.4.4", "", {}, "sha512-WZzeDOEtTOBK4Mdsar0IqEU5sMr3vSV2RqkAIzUEV2BHnUfKGyswWFPFwK5EeDo93K3FohSHbLAjj0s1Wzd+dg=="], - "js-base64": ["js-base64@3.7.8", "", {}, "sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow=="], "js-md4": ["js-md4@0.3.2", "", {}, "sha512-/GDnfQYsltsjRswQhN9fhv3EMw2sCpUdrdxyWDOUK7eyD++r3gRhzgiQgc/x4MAv2i1iuQ4lxO5mvqM3vj4bwA=="], @@ -3657,8 +3570,6 @@ "oidc-token-hash": ["oidc-token-hash@5.2.0", "", {}, "sha512-6gj2m8cJZ+iSW8bm0FXdGF0YhIQbKrfP4yWTNzxc31U6MOjfEmB1rHvlYvxI1B7t7BCi1F2vYTT6YhtQRG4hxw=="], - "omggif": ["omggif@1.0.10", "", {}, "sha512-LMJTtvgc/nugXj0Vcrrs68Mn2D1r0zf630VNtqtpI1FEO7e+O9FP4gqs9AcnBaSEeoHIPm28u6qgPR0oyEpGSw=="], - "on-exit-leak-free": ["on-exit-leak-free@2.1.2", "", {}, "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA=="], "on-finished": ["on-finished@2.4.1", "", { "dependencies": { "ee-first": "1.1.1" } }, "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg=="], @@ -3725,12 +3636,6 @@ "parent-module": ["parent-module@1.0.1", "", { "dependencies": { "callsites": "^3.0.0" } }, "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g=="], - "parse-bmfont-ascii": ["parse-bmfont-ascii@1.0.6", "", {}, "sha512-U4RrVsUFCleIOBsIGYOMKjn9PavsGOXxbvYGtMOEfnId0SVNsgehXh1DxUdVPLoxd5mvcEtvmKs2Mmf0Mpa1ZA=="], - - "parse-bmfont-binary": ["parse-bmfont-binary@1.0.6", "", {}, "sha512-GxmsRea0wdGdYthjuUeWTMWPqm2+FAd4GI8vCvhgJsFnoGhTrLhXDDupwTo7rXVAgaLIGoVHDZS9p/5XbSqeWA=="], - - "parse-bmfont-xml": ["parse-bmfont-xml@1.1.6", "", { "dependencies": { "xml-parse-from-string": "^1.0.0", "xml2js": "^0.5.0" } }, "sha512-0cEliVMZEhrFDwMh4SxIyVJpqYoOWDJ9P895tFuS+XuNzI5UBmBk5U5O4KuJdTnZpSBI4LFA2+ZiJaiwfSwlMA=="], - "parse-conflict-json": ["parse-conflict-json@5.0.1", "", { "dependencies": { "json-parse-even-better-errors": "^5.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" } }, "sha512-ZHEmNKMq1wyJXNwLxyHnluPfRAFSIliBvbK/UiOceROt4Xh9Pz0fq49NytIaeaCUf5VR86hwQ/34FCcNU5/LKQ=="], "parse-json": ["parse-json@8.3.0", "", { "dependencies": { "@babel/code-frame": "^7.26.2", "index-to-position": "^1.1.0", "type-fest": "^4.39.1" } }, "sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ=="], @@ -3771,8 +3676,6 @@ "pathval": ["pathval@2.0.1", "", {}, "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ=="], - "peek-readable": ["peek-readable@4.1.0", "", {}, "sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg=="], - "pend": ["pend@1.2.0", "", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="], "perfect-debounce": ["perfect-debounce@2.1.0", "", {}, "sha512-LjgdTytVFXeUgtHZr9WYViYSM/g8MkcTPYDlPa3cDqMirHjKiSZPYd6DoL7pK8AJQr+uWkQvCjHNdiMqsrJs+g=="], @@ -3789,8 +3692,6 @@ "pino-std-serializers": ["pino-std-serializers@7.1.0", "", {}, "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw=="], - "pixelmatch": ["pixelmatch@5.3.0", "", { "dependencies": { "pngjs": "^6.0.0" }, "bin": { "pixelmatch": "bin/pixelmatch" } }, "sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q=="], - "pkce-challenge": ["pkce-challenge@5.0.1", "", {}, "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ=="], "pkg-conf": ["pkg-conf@4.0.0", "", { "dependencies": { "find-up": "^6.0.0", "load-json-file": "^7.0.0" } }, "sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w=="], @@ -3799,8 +3700,6 @@ "pkg-up": ["pkg-up@3.1.0", "", { "dependencies": { "find-up": "^3.0.0" } }, "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA=="], - "planck": ["planck@1.5.0", "", { "peerDependencies": { "stage-js": "^1.0.0-alpha.12" } }, "sha512-dlvqJE+FscZgrGUXJ5ybd0o5bvZ5XXyZNbm08xGsXp9WjXeAyWSFT6n9s/1PQcUBo4546fDXA5RMA4wbDyZw6g=="], - "playwright": ["playwright@1.57.0", "", { "dependencies": { "playwright-core": "1.57.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw=="], "playwright-core": ["playwright-core@1.57.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ=="], @@ -3921,8 +3820,6 @@ "readable-stream": ["readable-stream@4.7.0", "", { "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", "process": "^0.11.10", "string_decoder": "^1.3.0" } }, "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg=="], - "readable-web-to-node-stream": ["readable-web-to-node-stream@3.0.4", "", { "dependencies": { "readable-stream": "^4.7.0" } }, "sha512-9nX56alTf5bwXQ3ZDipHJhusu9NTQJ/CVPtb/XHAJCXihZeitfJvIRS4GqQ/mfIoOE3IelHMrpayVrosdHBuLw=="], - "readdir-glob": ["readdir-glob@1.1.3", "", { "dependencies": { "minimatch": "^5.1.0" } }, "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA=="], "readdirp": ["readdirp@4.1.2", "", {}, "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg=="], @@ -4069,8 +3966,6 @@ "simple-git": ["simple-git@3.36.0", "", { "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", "@simple-git/args-pathspec": "^1.0.3", "@simple-git/argv-parser": "^1.1.0", "debug": "^4.4.0" } }, "sha512-cGQjLjK8bxJw4QuYT7gxHw3/IouVESbhahSsHrX97MzCL1gu2u7oy38W6L2ZIGECEfIBG4BabsWDPjBxJENv9Q=="], - "simple-xml-to-json": ["simple-xml-to-json@1.2.7", "", {}, "sha512-mz9VXphOxQWX3eQ/uXCtm6upltoN0DLx8Zb5T4TFC4FHB7S9FDPGre8CfLWqPWQQH/GrQYd2AXhhVM5LDpYx6Q=="], - "sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="], "slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="], @@ -4145,8 +4040,6 @@ "stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="], - "stage-js": ["stage-js@1.0.2", "", {}, "sha512-EWTRBYlg7Qv9wGUao99/PfRe3KaiQqWmgSvTOXvaWnu1Jk/q/vV8yJVu6bi/3EqDZeMVnCPAjheba6OFc5k1GQ=="], - "standard-as-callback": ["standard-as-callback@2.1.0", "", {}, "sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A=="], "statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="], @@ -4187,8 +4080,6 @@ "strnum": ["strnum@2.2.3", "", {}, "sha512-oKx6RUCuHfT3oyVjtnrmn19H1SiCqgJSg+54XqURKp5aCMbrXrhLjRN9TjuwMjiYstZ0MzDrHqkGZ5dFTKd+zg=="], - "strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="], - "structured-source": ["structured-source@4.0.0", "", { "dependencies": { "boundary": "^2.0.0" } }, "sha512-qGzRFNJDjFieQkl/sVOI2dUjHKRyL9dAJi2gCPGJLbJHBIkyOHxjuocpIEfbLioX+qSJpvbYdT49/YCdMznKxA=="], "styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="], @@ -4243,8 +4134,6 @@ "thread-stream": ["thread-stream@4.0.0", "", { "dependencies": { "real-require": "^0.2.0" } }, "sha512-4iMVL6HAINXWf1ZKZjIPcz5wYaOdPhtO8ATvZ+Xqp3BTdaqtAwQkNmKORqcIo5YkQqGXq5cwfswDwMqqQNrpJA=="], - "three": ["three@0.177.0", "", {}, "sha512-EiXv5/qWAaGI+Vz2A+JfavwYCMdGjxVsrn3oBwllUoqYeaBO75J63ZfyaQKoiLrqNHoTlUc6PFgMXnS0kI45zg=="], - "thunky": ["thunky@1.1.0", "", {}, "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA=="], "time-zone": ["time-zone@1.0.0", "", {}, "sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA=="], @@ -4253,8 +4142,6 @@ "tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="], - "tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="], - "tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="], "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="], @@ -4275,8 +4162,6 @@ "toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="], - "token-types": ["token-types@4.2.1", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "ieee754": "^1.2.1" } }, "sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ=="], - "toml": ["toml@4.1.1", "", {}, "sha512-EBJnVBr3dTXdA89WVFoAIPUqkBjxPMwRqsfuo1r240tKFHXv3zgca4+NJib/h6TyvGF7vOawz0jGuryJCdNHrw=="], "tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="], @@ -4373,8 +4258,6 @@ "use-sync-external-store": ["use-sync-external-store@1.6.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w=="], - "utif2": ["utif2@4.1.0", "", { "dependencies": { "pako": "^1.0.11" } }, "sha512-+oknB9FHrJ7oW7A2WZYajOcv4FcDR4CfoGB0dPNfxbi4GO05RRnFmt5oa23+9w32EanrYcSJWspUiJkLMs+37w=="], - "util": ["util@0.12.5", "", { "dependencies": { "inherits": "^2.0.3", "is-arguments": "^1.0.4", "is-generator-function": "^1.0.7", "is-typed-array": "^1.1.3", "which-typed-array": "^1.1.2" } }, "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA=="], "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="], @@ -4467,8 +4350,6 @@ "xdg-basedir": ["xdg-basedir@5.1.0", "", {}, "sha512-GCPAHLvrIH13+c0SuacwvRYj2SxJXQ4kaVTT5xgL3kPrz56XxkF21IGhjSE1+W0aw7gpBWRGXLCPnPby6lSpmQ=="], - "xml-parse-from-string": ["xml-parse-from-string@1.0.1", "", {}, "sha512-ErcKwJTF54uRzzNMXq2X5sMIy88zJvfN2DmdoQvy7PAFJ+tPRU6ydWuOKNMyfmOjdyBQTFREi60s0Y0SyI0G0g=="], - "xml2js": ["xml2js@0.5.0", "", { "dependencies": { "sax": ">=0.6.0", "xmlbuilder": "~11.0.0" } }, "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA=="], "xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="], @@ -4553,8 +4434,6 @@ "@antfu/install-pkg/tinyexec": ["tinyexec@1.1.1", "", {}, "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg=="], - "@anthropic-ai/sdk/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "@aws-crypto/sha1-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], "@aws-crypto/sha256-browser/@smithy/util-utf8": ["@smithy/util-utf8@2.3.0", "", { "dependencies": { "@smithy/util-buffer-from": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A=="], @@ -4611,56 +4490,14 @@ "@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@jimp/core/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="], - - "@jimp/js-png/pngjs": ["pngjs@7.0.0", "", {}, "sha512-LKWqWJRhstyYo9pGvgor/ivk2w94eSjE3RGVuzLGlr3NmD8bf7RcYGze1mNdEHRP6TRP6rMuDHk5t44hnTRyow=="], - - "@jimp/plugin-blit/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-circle/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-color/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-contain/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-cover/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-crop/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-displace/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-fisheye/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-flip/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-mask/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-print/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-quantize/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-resize/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-rotate/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/plugin-threshold/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - - "@jimp/types/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], - "@kilocode/kilo-docs/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="], "@kilocode/kilo-gateway/@ai-sdk/openai": ["@ai-sdk/openai@3.0.48", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ALmj/53EXpcRqMbGpPJPP4UOSWw0q4VGpnDo7YctvsynjkrKDmoneDG/1a7VQnSPYHnJp6tTRMf5ZdxZ5whulg=="], "@kilocode/kilo-gateway/@ai-sdk/openai-compatible": ["@ai-sdk/openai-compatible@2.0.37", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.21" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-+POSFVcgiu47BK64dhsI6OpcDC0/VAE2ZSaXdXGNNhpC/ava++uSRJYks0k2bpfY0wwCTgpAWZsXn/dG2Yppiw=="], - "@kilocode/kilo-gateway/@opentui/core": ["@opentui/core@0.1.75", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.75", "@opentui/core-darwin-x64": "0.1.75", "@opentui/core-linux-arm64": "0.1.75", "@opentui/core-linux-x64": "0.1.75", "@opentui/core-win32-arm64": "0.1.75", "@opentui/core-win32-x64": "0.1.75", "bun-webgpu": "0.1.4", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-8ARRZxSG+BXkJmEVtM2DQ4se7DAF1ZCKD07d+AklgTr2mxCzmdxxPbOwRzboSQ6FM7qGuTVPVbV4O2W9DpUmoA=="], - - "@kilocode/kilo-gateway/@opentui/solid": ["@opentui/solid@0.1.75", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.75", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.9", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.9" } }, "sha512-WjKsZIfrm29znfRlcD9w3uUn/+uvoy2MmeoDwTvg1YOa0OjCTCmjZ43L9imp0m9S4HmVU8ma6o2bR4COzcyDdg=="], - "@kilocode/kilo-indexing/glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="], - "@manypkg/find-root/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "@manypkg/find-root/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], "@manypkg/find-root/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="], @@ -4717,8 +4554,6 @@ "@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="], - "@opencode-ai/plugin/effect": ["effect@4.0.0-beta.57", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-rg32VgXnLKaPRs9tbRDaZ5jxmzNY7ojXt85gSHGUTwdlbWH5Ik+OCUY2q14TXliygPGoHwCAvNWS4bQJOqf00g=="], - "@opencode-ai/storybook/@storybook/addon-a11y": ["@storybook/addon-a11y@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "axe-core": "^4.2.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-5k6lpgfIeLxvNhE8v3wEzdiu73ONKjF4gmH1AHvfqYd8kIVzQJai0KCDxgvqNncXHQhIWkaf1fg6+9hKaYJyaw=="], "@opencode-ai/storybook/@storybook/addon-docs": ["@storybook/addon-docs@10.3.5", "", { "dependencies": { "@mdx-js/react": "^3.0.0", "@storybook/csf-plugin": "10.3.5", "@storybook/icons": "^2.0.1", "@storybook/react-dom-shim": "10.3.5", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "ts-dedent": "^2.0.0" }, "peerDependencies": { "storybook": "^10.3.5" } }, "sha512-WuHbxia/o5TX4Rg/IFD0641K5qId/Nk0dxhmAUNoFs5L0+yfZUwh65XOBbzXqrkYmYmcVID4v7cgDRmzstQNkA=="], @@ -4765,10 +4600,6 @@ "@solid-primitives/resize-observer/@solid-primitives/rootless": ["@solid-primitives/rootless@1.5.3", "", { "dependencies": { "@solid-primitives/utils": "^6.4.0" }, "peerDependencies": { "solid-js": "^1.6.12" } }, "sha512-N8cIDAHbWcLahNRLr0knAAQvXyEdEMoAZvIMZKmhNb1mlx9e2UOv9BRD5YNwQUJwbNoYVhhLwFOEOcVXFx0HqA=="], - "@standard-community/standard-json/effect": ["effect@4.0.0-beta.57", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-rg32VgXnLKaPRs9tbRDaZ5jxmzNY7ojXt85gSHGUTwdlbWH5Ik+OCUY2q14TXliygPGoHwCAvNWS4bQJOqf00g=="], - - "@standard-community/standard-openapi/effect": ["effect@4.0.0-beta.57", "", { "dependencies": { "@standard-schema/spec": "^1.1.0", "fast-check": "^4.6.0", "find-my-way-ts": "^0.1.6", "ini": "^6.0.0", "kubernetes-types": "^1.30.0", "msgpackr": "^1.11.9", "multipasta": "^0.2.7", "toml": "^4.1.1", "uuid": "^13.0.0", "yaml": "^2.8.3" } }, "sha512-rg32VgXnLKaPRs9tbRDaZ5jxmzNY7ojXt85gSHGUTwdlbWH5Ik+OCUY2q14TXliygPGoHwCAvNWS4bQJOqf00g=="], - "@storybook/addon-links/storybook": ["storybook@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "@webcontainer/env": "^1.1.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", "open": "^10.2.0", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.18.0" }, "peerDependencies": { "prettier": "^2 || ^3" }, "optionalPeers": ["prettier"], "bin": "./dist/bin/dispatcher.js" }, "sha512-uBSZu/GZa9aEIW3QMGvdQPMZWhGxSe4dyRWU8B3/Vd47Gy/XLC7tsBxRr13txmmPOEDHZR94uLuq0H50fvuqBw=="], "@storybook/addon-onboarding/storybook": ["storybook@10.3.5", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", "@testing-library/jest-dom": "^6.9.1", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "@webcontainer/env": "^1.1.1", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", "open": "^10.2.0", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.18.0" }, "peerDependencies": { "prettier": "^2 || ^3" }, "optionalPeers": ["prettier"], "bin": "./dist/bin/dispatcher.js" }, "sha512-uBSZu/GZa9aEIW3QMGvdQPMZWhGxSe4dyRWU8B3/Vd47Gy/XLC7tsBxRr13txmmPOEDHZR94uLuq0H50fvuqBw=="], @@ -4809,30 +4640,6 @@ "@textlint/linter-formatter/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "@types/cacache/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/cross-spawn/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/mssql/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/node-fetch/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/npm-registry-fetch/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/npmcli__arborist/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/npmlog/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/pacote/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/qrcode/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/readable-stream/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/ssri/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - - "@types/ws/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "@typescript-eslint/visitor-keys/eslint-visitor-keys": ["eslint-visitor-keys@5.0.1", "", {}, "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA=="], "@vscode/ripgrep/yauzl": ["yauzl@2.10.0", "", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="], @@ -4869,8 +4676,6 @@ "ai-gateway-provider/@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@2.5.1", "", { "peerDependencies": { "ai": "^6.0.0", "zod": "^3.25.0 || ^4.0.0" } }, "sha512-r1fJL1Cb3gQDa2MpWH/sfx1BsEW0uzlRriJM6eihaKqbtKDmZoBisF32VcVaQYassighX7NGCkF68EsrZA43uQ=="], - "apache-arrow/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "archiver-utils/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], "archiver-utils/is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="], @@ -4905,8 +4710,6 @@ "buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "bun-types/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "c12/chokidar": ["chokidar@5.0.0", "", { "dependencies": { "readdirp": "^5.0.0" } }, "sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw=="], "c12/dotenv": ["dotenv@17.4.2", "", {}, "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw=="], @@ -4999,8 +4802,6 @@ "gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="], - "image-q/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="], "isomorphic-git/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="], @@ -5087,10 +4888,6 @@ "openid-client/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="], - "opentui-spinner/@opentui/core": ["@opentui/core@0.1.105", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.105", "@opentui/core-darwin-x64": "0.1.105", "@opentui/core-linux-arm64": "0.1.105", "@opentui/core-linux-x64": "0.1.105", "@opentui/core-win32-arm64": "0.1.105", "@opentui/core-win32-x64": "0.1.105", "bun-webgpu": "0.1.5", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-vllSOOCW6VIThV/96GRLJ1IxIBuR+ci6FDvnPIAG4s7SJ/FW6zAkqDn1xrtBwwk/lM3QWjLqy8BZc+zwWvveJA=="], - - "opentui-spinner/@opentui/solid": ["@opentui/solid@0.1.105", "", { "dependencies": { "@babel/core": "7.28.0", "@babel/preset-typescript": "7.27.1", "@opentui/core": "0.1.105", "babel-plugin-module-resolver": "5.0.2", "babel-preset-solid": "1.9.10", "entities": "7.0.1", "s-js": "^0.4.9" }, "peerDependencies": { "solid-js": "1.9.11" } }, "sha512-uxnaMP802sCI487pv/Hk9xdFdIj9mkg3eNliAqbqR0Shmd4phcjKEZvPRpijjmI99j4s9nul71jzF3h1oz31Nw=="], - "ora/cli-spinners": ["cli-spinners@2.9.2", "", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="], "ora/log-symbols": ["log-symbols@6.0.0", "", { "dependencies": { "chalk": "^5.3.0", "is-unicode-supported": "^1.3.0" } }, "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw=="], @@ -5105,8 +4902,6 @@ "parse5/entities": ["entities@6.0.1", "", {}, "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g=="], - "pixelmatch/pngjs": ["pngjs@6.0.0", "", {}, "sha512-TRzzuFRRmEoSW/p1KVAmiOgPco2Irlah+bGFCeNfJXxxYGwSw7YwAOAcd7X28K/m5bjBWKsC29KyoMfHbypayg=="], - "pkg-conf/find-up": ["find-up@6.3.0", "", { "dependencies": { "locate-path": "^7.1.0", "path-exists": "^5.0.0" } }, "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw=="], "pkg-types/confbox": ["confbox@0.1.8", "", {}, "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w=="], @@ -5123,8 +4918,6 @@ "pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="], - "protobufjs/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "proxy-addr/ipaddr.js": ["ipaddr.js@1.9.1", "", {}, "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="], "qrcode/yargs": ["yargs@15.4.1", "", { "dependencies": { "cliui": "^6.0.0", "decamelize": "^1.2.0", "find-up": "^4.1.0", "get-caller-file": "^2.0.1", "require-directory": "^2.1.1", "require-main-filename": "^2.0.0", "set-blocking": "^2.0.0", "string-width": "^4.2.0", "which-module": "^2.0.0", "y18n": "^4.0.0", "yargs-parser": "^18.1.2" } }, "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A=="], @@ -5191,16 +4984,12 @@ "tar-fs/tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="], - "tedious/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "tedious/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="], "test-exclude/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="], "to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="], - "token-types/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "tree-sitter-bash/node-addon-api": ["node-addon-api@8.7.0", "", {}, "sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA=="], "url/punycode": ["punycode@1.3.2", "", {}, "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="], @@ -5251,8 +5040,6 @@ "@ai-sdk/vercel/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], "@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="], @@ -5273,32 +5060,10 @@ "@kilocode/kilo-gateway/@ai-sdk/openai-compatible/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.75", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gGaGZjkFpqcXJk6321JzhRl66pM2VxBlI470L8W4DQUW4S6iDT1R9L7awSzGB4Cn9toUl7DTV8BemaXZYXV4SA=="], - - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.75", "", { "os": "darwin", "cpu": "x64" }, "sha512-tPlvqQI0whZ76amHydpJs5kN+QeWAIcFbI8RAtlAo9baj2EbxTDC+JGwgb9Fnt0/YQx831humbtaNDhV2Jt1bw=="], - - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.75", "", { "os": "linux", "cpu": "arm64" }, "sha512-nVxIQ4Hqf84uBergDpWiVzU6pzpjy6tqBHRQpySxZ2flkJ/U6/aMEizVrQ1jcgIdxZtvqWDETZhzxhG0yDx+cw=="], - - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.75", "", { "os": "linux", "cpu": "x64" }, "sha512-1CnApef4kxA+ORyLfbuCLgZfEjp4wr3HjFnt7FAfOb73kIZH82cb7JYixeqRyy9eOcKfKqxLmBYy3o8IDkc4Rg=="], - - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.75", "", { "os": "win32", "cpu": "arm64" }, "sha512-j0UB95nmkYGNzmOrs6GqaddO1S90R0YC6IhbKnbKBdjchFPNVLz9JpexAs6MBDXPZwdKAywMxtwG2h3aTJtxng=="], - - "@kilocode/kilo-gateway/@opentui/core/@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.75", "", { "os": "win32", "cpu": "x64" }, "sha512-ESpVZVGewe3JkB2TwrG3VRbkxT909iPdtvgNT7xTCIYH2VB4jqZomJfvERPTE0tvqAZJm19mHECzJFI8asSJgQ=="], - - "@kilocode/kilo-gateway/@opentui/core/bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="], - - "@kilocode/kilo-gateway/@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], - - "@kilocode/kilo-gateway/@opentui/solid/babel-preset-solid": ["babel-preset-solid@1.9.9", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.1" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.8" }, "optionalPeers": ["solid-js"] }, "sha512-pCnxWrciluXCeli/dj5PIEHgbNzim3evtTn12snjqqg8QZWJNMjH1AWIp4iG/tbVjqQ72aBEymMSagvmgxubXw=="], - - "@manypkg/find-root/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "@manypkg/find-root/find-up/locate-path": ["locate-path@5.0.0", "", { "dependencies": { "p-locate": "^4.1.0" } }, "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g=="], "@morphllm/morphsdk/ai/@ai-sdk/gateway": ["@ai-sdk/gateway@3.0.95", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@ai-sdk/provider-utils": "4.0.23", "@vercel/oidc": "3.1.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ZmUNNbZl3V42xwQzPaNUi+s8eqR2lnrxf0bvB6YbLXpLjHYv0k2Y78t12cNOfY0bxGeuVVTLyk856uLuQIuXEQ=="], - "@morphllm/morphsdk/openai/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "@morphllm/morphsdk/openai/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="], "@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="], @@ -5333,10 +5098,6 @@ "@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="], - "@opencode-ai/plugin/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@opencode-ai/plugin/effect/uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], - "@opencode-ai/storybook/@storybook/addon-docs/@storybook/csf-plugin": ["@storybook/csf-plugin@10.3.5", "", { "dependencies": { "unplugin": "^2.3.5" }, "peerDependencies": { "esbuild": "*", "rollup": "*", "storybook": "^10.3.5", "vite": "*", "webpack": "*" }, "optionalPeers": ["esbuild", "rollup", "vite", "webpack"] }, "sha512-qlEzNKxOjq86pvrbuMwiGD/bylnsXk1dg7ve0j77YFjEEchqtl7qTlrXvFdNaLA89GhW6D/EV6eOCu/eobPDgw=="], "@opencode-ai/storybook/@storybook/addon-docs/@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.3.5", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.3.5" } }, "sha512-Gw8R7XZm0zSUH0XAuxlQJhmizsLzyD6x00KOlP6l7oW9eQHXGfxg3seNDG3WrSAcW07iP1/P422kuiriQlOv7g=="], @@ -5355,14 +5116,6 @@ "@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@standard-community/standard-json/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@standard-community/standard-json/effect/uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], - - "@standard-community/standard-openapi/effect/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - - "@standard-community/standard-openapi/effect/uuid": ["uuid@13.0.0", "", { "bin": { "uuid": "dist-node/bin/uuid" } }, "sha512-XQegIaBTVUjSHliKqcnFqYypAd4S+WCYt5NIeRs6w/UAry7z8Y9j5ZwRRL4kzq9U3sD6v+85er9FvkEaBpji2w=="], - "@storybook/addon-links/storybook/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], "@storybook/addon-onboarding/storybook/open": ["open@10.2.0", "", { "dependencies": { "default-browser": "^5.2.1", "define-lazy-prop": "^3.0.0", "is-inside-container": "^1.0.0", "wsl-utils": "^0.1.0" } }, "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA=="], @@ -5405,30 +5158,6 @@ "@textlint/linter-formatter/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="], - "@types/cacache/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/cross-spawn/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/mssql/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/node-fetch/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npm-registry-fetch/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npmcli__arborist/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/npmlog/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/pacote/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/qrcode/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/readable-stream/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/ssri/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - - "@types/ws/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "@vscode/ripgrep/yauzl/buffer-crc32": ["buffer-crc32@0.2.13", "", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="], "@vscode/test-cli/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], @@ -5471,8 +5200,6 @@ "ai-gateway-provider/@ai-sdk/xai/@ai-sdk/provider-utils": ["@ai-sdk/provider-utils@4.0.21", "", { "dependencies": { "@ai-sdk/provider": "3.0.8", "@standard-schema/spec": "^1.1.0", "eventsource-parser": "^3.0.6" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-MtFUYI1/8mgDvRmaBDjbLJPFFrMG777AvSgyIFQtZHIMzm88R/12vYBBpnk7pfiWLFE1DSZzY4WDYzGbKAcmiw=="], - "apache-arrow/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "archiver-utils/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "archiver-utils/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], @@ -5503,8 +5230,6 @@ "bl/buffer/ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="], - "bun-types/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "c12/chokidar/readdirp": ["readdirp@5.0.0", "", {}, "sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ=="], "c8/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="], @@ -5609,14 +5334,10 @@ "gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="], - "image-q/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "jszip/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], - "kilo-code/openai/@types/node": ["@types/node@22.13.9", "", { "dependencies": { "undici-types": "~6.20.0" } }, "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw=="], - "lazystream/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="], "lazystream/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="], @@ -5647,26 +5368,6 @@ "opencontrol/@modelcontextprotocol/sdk/zod-to-json-schema": ["zod-to-json-schema@3.25.2", "", { "peerDependencies": { "zod": "^3.25.28 || ^4" } }, "sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA=="], - "opentui-spinner/@opentui/core/@opentui/core-darwin-arm64": ["@opentui/core-darwin-arm64@0.1.105", "", { "os": "darwin", "cpu": "arm64" }, "sha512-1pIL7aer9amwj8EpYoMNtvavKetIe+nX8uBRmYsMQb+KvJoUAZUqENfRW+qHE5WrsOyxx8/QoyXTHw15GG5iLQ=="], - - "opentui-spinner/@opentui/core/@opentui/core-darwin-x64": ["@opentui/core-darwin-x64@0.1.105", "", { "os": "darwin", "cpu": "x64" }, "sha512-hLIRSWlK3gY2NRXJGWiTBiMYSmRDjOYFZF6WtUVXhY2SL3sp08dhmr/6dmAVH+3pKCsCipLEsrrcQX6SAihCTA=="], - - "opentui-spinner/@opentui/core/@opentui/core-linux-arm64": ["@opentui/core-linux-arm64@0.1.105", "", { "os": "linux", "cpu": "arm64" }, "sha512-jlRKfPkozTZEkHEePuCWYcTIUtPm+ieInAwGVqGmjbvqjxdVv1/W/Dt6LEZ/9jpRiOPd+FjXAfLe6wa/XWHr+w=="], - - "opentui-spinner/@opentui/core/@opentui/core-linux-x64": ["@opentui/core-linux-x64@0.1.105", "", { "os": "linux", "cpu": "x64" }, "sha512-kfWS1WMg6qHShmxZX9s1tZc/8JcXw6uyy2UtyTbJdRFExtXGH37oKHi8QK8iPL2ExCx4z7zqVnVJfO3X/Wh7lA=="], - - "opentui-spinner/@opentui/core/@opentui/core-win32-arm64": ["@opentui/core-win32-arm64@0.1.105", "", { "os": "win32", "cpu": "arm64" }, "sha512-UFx6A8OpBVbGWK6OAw4GqAqKZgIITJfSOd35pG9yDVKQouHN2OGc2HeeXrH2A4h42p40Xl6IfcqqfllkpC13Dg=="], - - "opentui-spinner/@opentui/core/@opentui/core-win32-x64": ["@opentui/core-win32-x64@0.1.105", "", { "os": "win32", "cpu": "x64" }, "sha512-f9FqqUmxehwhF+cgyazm0YT0v0BYTTCPzd6eztqhl74N3x/kC+jOOz2rdJDC/tTBo1JVsF64KupOnhIs6/Cogg=="], - - "opentui-spinner/@opentui/core/bun-ffi-structs": ["bun-ffi-structs@0.1.2", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-Lh1oQAYHDcnesJauieA4UNkWGXY9hYck7OA5IaRwE3Bp6K2F2pJSNYqq+hIy7P3uOvo3km3oxS8304g5gDMl/w=="], - - "opentui-spinner/@opentui/core/bun-webgpu": ["bun-webgpu@0.1.5", "", { "dependencies": { "@webgpu/types": "^0.1.60" }, "optionalDependencies": { "bun-webgpu-darwin-arm64": "^0.1.5", "bun-webgpu-darwin-x64": "^0.1.5", "bun-webgpu-linux-x64": "^0.1.5", "bun-webgpu-win32-x64": "^0.1.5" } }, "sha512-91/K6S5whZKX7CWAm9AylhyKrLGRz6BUiiPiM/kXadSnD4rffljCD/q9cNFftm5YXhx4MvLqw33yEilxogJvwA=="], - - "opentui-spinner/@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="], - - "opentui-spinner/@opentui/solid/babel-preset-solid": ["babel-preset-solid@1.9.10", "", { "dependencies": { "babel-plugin-jsx-dom-expressions": "^0.40.3" }, "peerDependencies": { "@babel/core": "^7.0.0", "solid-js": "^1.9.10" }, "optionalPeers": ["solid-js"] }, "sha512-HCelrgua/Y+kqO8RyL04JBWS/cVdrtUv/h45GntgQY+cJl4eBcKkCDV3TdMjtKx1nXwRaR9QXslM/Npm1dxdZQ=="], - "ora/log-symbols/is-unicode-supported": ["is-unicode-supported@1.3.0", "", {}, "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ=="], "p-locate/p-limit/yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="], @@ -5679,8 +5380,6 @@ "posthog-js/@opentelemetry/resources/@opentelemetry/core": ["@opentelemetry/core@2.7.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-DT12SXVwV2eoJrGf4nnsvZojxxeQo+LlNAsoYGRRObPWTeN6APiqZ2+nqDCQDvQX40eLi1AePONS0onoASp3yQ=="], - "protobufjs/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="], "qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="], @@ -5711,8 +5410,6 @@ "tar-fs/tar-stream/readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="], - "tedious/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "test-exclude/glob/jackspeak": ["jackspeak@3.4.3", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw=="], "test-exclude/glob/minimatch": ["minimatch@9.0.9", "", { "dependencies": { "brace-expansion": "^2.0.2" } }, "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg=="], @@ -5739,14 +5436,10 @@ "@kilocode/kilo-gateway/@ai-sdk/openai/@ai-sdk/provider-utils/@standard-schema/spec": ["@standard-schema/spec@1.1.0", "", {}, "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w=="], - "@kilocode/kilo-gateway/@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "@manypkg/find-root/find-up/locate-path/p-locate": ["p-locate@4.1.0", "", { "dependencies": { "p-limit": "^2.2.0" } }, "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A=="], "@morphllm/morphsdk/ai/@ai-sdk/gateway/@vercel/oidc": ["@vercel/oidc@3.1.0", "", {}, "sha512-Fw28YZpRnA3cAHHDlkt7xQHiJ0fcL+NRcIqsocZQUSmbzeIKRpwttJjik5ZGanXP+vlA4SbTg+AbA3bP363l+w=="], - "@morphllm/morphsdk/openai/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "@octokit/graphql/@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="], "@octokit/rest/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="], @@ -5859,8 +5552,6 @@ "gray-matter/js-yaml/argparse/sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="], - "kilo-code/openai/@types/node/undici-types": ["undici-types@6.20.0", "", {}, "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg=="], - "mocha/glob/jackspeak/@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="], "mocha/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="], @@ -5875,8 +5566,6 @@ "mocha/yargs/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="], - "opentui-spinner/@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="], - "pkg-conf/find-up/locate-path/p-locate": ["p-locate@6.0.0", "", { "dependencies": { "p-limit": "^4.0.0" } }, "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw=="], "pkg-up/find-up/locate-path/p-locate": ["p-locate@3.0.0", "", { "dependencies": { "p-limit": "^2.0.0" } }, "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ=="], diff --git a/nix/hashes.json b/nix/hashes.json index e8171c93a62..db28ef66415 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-EbXkvlbexL1Gyy4vvGG5j+JWjv7SsVk6T5YnDfo3AQY=", - "aarch64-linux": "sha256-+MuJE4XGr0dArD/HuozaoK9Oymfgvx1CisE/Sm4ZstY=", - "aarch64-darwin": "sha256-Qdk+tZLydGld471ApL1cxfd85QQNFelTfqq7uAznfK4=", - "x86_64-darwin": "sha256-Fo6W65MfAcXaulBGCaE7+GfHtq3VVJyVDJpIENvR7lQ=" + "x86_64-linux": "sha256-vI06afIL8mL/Rt33Wk2S2kLzrlR3EHqv5kfy0qgO2Zg=", + "aarch64-linux": "sha256-68uA7dKxOXmIRHJ3BI2K2wc1Pkag2cWpp9fLtbS6Ehk=", + "aarch64-darwin": "sha256-oRy74XjENuCxOmPrfEmM4UXoZQQXM5VQlLXMx5SmX+k=", + "x86_64-darwin": "sha256-TjcaVBh40HZk2kKwAunrrl/KYrvEk13bLiBdcUzWSQA=" } } diff --git a/package.json b/package.json index 76b61df1dd3..c1f7070041a 100644 --- a/package.json +++ b/package.json @@ -139,13 +139,16 @@ "fastify": ">=5.8.3", "diff": "8.0.4", "dompurify": "3.4.2", - "happy-dom": ">=20.8.9" + "happy-dom": ">=20.8.9", + "@opentui/core": "catalog:", + "@opentui/solid": "catalog:", + "solid-js": "catalog:" }, "patchedDependencies": { "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", "@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch", "solid-js@1.9.10": "patches/solid-js@1.9.10.patch" }, - "version": "7.3.12", + "version": "7.3.14", "peerDependencies": {} } diff --git a/packages/core/package.json b/packages/core/package.json index 3936f230288..f778b34bb04 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "7.3.12", + "version": "7.3.14", "name": "@opencode-ai/core", "type": "module", "license": "MIT", diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index ccdb1a18d60..c09d9006bb7 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.3.12" +version = "7.3.14" 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.3.12/opencode-darwin-arm64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.14/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.3.12/opencode-darwin-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.14/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.12/opencode-linux-arm64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.14/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.3.12/opencode-linux-x64.tar.gz" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.14/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.3.12/opencode-windows-x64.zip" +archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.3.14/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/kilo-docs/package.json b/packages/kilo-docs/package.json index 6a34ff6095c..6bac0781fd0 100644 --- a/packages/kilo-docs/package.json +++ b/packages/kilo-docs/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-docs", - "version": "7.3.12", + "version": "7.3.14", "private": true, "scripts": { "dev": "next dev --webpack --port 3002", diff --git a/packages/kilo-docs/pages/ai-providers/mistral.md b/packages/kilo-docs/pages/ai-providers/mistral.md index 684191febc1..aaa3e6beb1f 100644 --- a/packages/kilo-docs/pages/ai-providers/mistral.md +++ b/packages/kilo-docs/pages/ai-providers/mistral.md @@ -76,7 +76,7 @@ Other Mistral models do not get automatic reasoning variants, even if they appea ## Using Codestral -[Codestral](https://docs.mistral.ai/capabilities/code_generation/) is a model specifically designed for code generation and interaction. +[Codestral](https://docs.mistral.ai/vibe/code/overview) is a model specifically designed for code generation and interaction. Only for Codestral you could use different endpoints (Default: codestral.mistral.ai). For the La Platforme API Key change the **Codestral Base Url** to: https://api.mistral.ai diff --git a/packages/kilo-docs/pages/code-with-ai/agents/model-selection.md b/packages/kilo-docs/pages/code-with-ai/agents/model-selection.md index b0f7c227cec..947546cfbd2 100644 --- a/packages/kilo-docs/pages/code-with-ai/agents/model-selection.md +++ b/packages/kilo-docs/pages/code-with-ai/agents/model-selection.md @@ -52,12 +52,22 @@ While the specifics change constantly, some principles stay consistent: **For everyday coding**: Mid-tier models often provide the best balance of speed, cost, and quality. They're fast enough to keep your flow state intact and capable enough for most tasks. -**For budget-conscious work**: Newer efficient models keep surprising us with price-to-performance ratios. DeepSeek, Qwen, and similar models can handle more than you'd expect. +**For budget-conscious work**: Newer efficient models keep surprising us with price-to-performance ratios. DeepSeek, Qwen, and similar models can handle more than you'd expect. See the [free and budget picks](#free-and-budget-model-picks) below. **For local/private work**: Ollama and LM Studio let you run models locally. The tradeoff is usually speed and capability for privacy and zero API costs. **Using an unlisted model?** You can register any model — including fine-tunes, newly released models, or custom local models — by adding it to your config file. See [Custom Models](/docs/code-with-ai/agents/custom-models) for details. +## Free and Budget Model Picks + +You don't need a paid API key to use Kilo Code productively. The fastest way to start for free is [Auto Model Free](/docs/code-with-ai/agents/auto-model) (`kilo-auto/free`), which routes to the best available free models automatically. See [Using Kilo for Free](/docs/getting-started/using-kilo-for-free) for the full zero-cost setup. + +If you prefer to pick models yourself, type `free` in the model picker to filter by free models, or browse the full list at [kilo.ai/models](https://kilo.ai/models). + +{% callout type="info" %} +Free model availability changes as providers adjust promotional periods. Check [kilo.ai/models](https://kilo.ai/models) for the live list. +{% /callout %} + ## Context Windows Matter One thing that doesn't change: context window size matters for your workflow. diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/agentmanager/full-screen-diff-with-collapsed-context-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/agentmanager/full-screen-diff-with-collapsed-context-chromium-linux.png new file mode 100644 index 00000000000..bc87566f6c4 --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/agentmanager/full-screen-diff-with-collapsed-context-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f5e9dd9a8b232e960fbc1925a2447a7634b2db241f6fe9b9ba8527665a5ca4c4 +size 14248 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/error-display-data-policy-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/error-display-data-policy-chromium-linux.png new file mode 100644 index 00000000000..010968eb6a0 --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/error-display-data-policy-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e3050c782d797be7dad951b76199df2c87195415e699d3e8481bbf40ad0dfccf +size 10073 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/suggest-bar-review-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/suggest-bar-review-chromium-linux.png index 27e9b8983a1..b26984c98f1 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/suggest-bar-review-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/suggest-bar-review-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:eee5f5d61cf2ac9ad0b987a8b220d76c503be0d11447766e6669da4684698c82 -size 6130 +oid sha256:bbdf3df267cb9c32febbaa486b7a63e8561e1d968bda24bb5278634307eac873 +size 5962 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-failed-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-failed-chromium-linux.png new file mode 100644 index 00000000000..f011a8544ec --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-failed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6d0ccfb86ad9a6eaab64e1afe455a96cd4c1443f12fbd47698a4730724712b6 +size 931 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-unknown-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-unknown-chromium-linux.png new file mode 100644 index 00000000000..00e71e588fb --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/chat/turn-outcome-unknown-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4544323cd000c4f43b88c420bbf2b7cb72317b6d40b0b0f3c690fb9deabaa27d +size 3737 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/history-sessionlist/with-items-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/history-sessionlist/with-items-chromium-linux.png index 74a826d3453..8f2b4c1f3fa 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/history-sessionlist/with-items-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/history-sessionlist/with-items-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:65686e2d0978adcf09ae504d9414e2d81f304eb18ff2275be7a33a9c3579a5e5 -size 18209 +oid sha256:32fa296aeee4f45f1cefe49d8eaca08099a8b3b8c23d4e9cdec803ce7fd1f0a1 +size 18207 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-empty-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-empty-chromium-linux.png new file mode 100644 index 00000000000..fd503e50e61 --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-empty-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7338febdf802b5ce501773be164e9da152fb7903e9b16807bd8751fa38f208ed +size 10310 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-installed-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-installed-chromium-linux.png new file mode 100644 index 00000000000..071927ae44d --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-installed-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f7e075b4961d3a62c8deda6b481f64cb8777d05183a9c10d0dd2373b7972d3ab +size 53678 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-items-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-items-chromium-linux.png new file mode 100644 index 00000000000..158e7e0bdcc --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/agents-tab-with-items-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b0dd1dc26b28d354ecd14c53dd1b9e6158a161f47152f30299ba4c0827ce1674 +size 50904 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/installed-mode-card-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/installed-agent-card-chromium-linux.png similarity index 100% rename from packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/installed-mode-card-chromium-linux.png rename to packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/installed-agent-card-chromium-linux.png diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-empty-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-empty-chromium-linux.png deleted file mode 100644 index f190c5fac6e..00000000000 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-empty-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c925148c349c6ab1f14190a2a379aa24869de35e5b77455fa15d8868eb08343 -size 5943 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-installed-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-installed-chromium-linux.png deleted file mode 100644 index 180572497e7..00000000000 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-installed-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5094e214a52bac4627f8fe280f4818c986753c49f160bf5295f21122054ea72f -size 53684 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-items-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-items-chromium-linux.png deleted file mode 100644 index b8b99ed8d51..00000000000 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/modes-tab-with-items-chromium-linux.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:83a70ef1260f77c3017db90a918ee77c332c065bfc047e0f206948bb5dde83b9 -size 50888 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/single-mode-card-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/single-agent-card-chromium-linux.png similarity index 100% rename from packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/single-mode-card-chromium-linux.png rename to packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/marketplace/single-agent-card-chromium-linux.png diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-catalog-loading-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-catalog-loading-chromium-linux.png new file mode 100644 index 00000000000..6f601a9608e --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-catalog-loading-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9d70e12fc78142601de74977fea330a91f3662851cc8f56023a6ec819724dbb8 +size 48958 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-model-preset-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-model-preset-chromium-linux.png new file mode 100644 index 00000000000..7c064e2b69e --- /dev/null +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/indexing-kilo-model-preset-chromium-linux.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d7ad739b2099b5b35abf3989bca8e8f63c2926906decfddf7530d6b97fb0e6b1 +size 50711 diff --git a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/models-autocomplete-open-chromium-linux.png b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/models-autocomplete-open-chromium-linux.png index 06a45f9ca3c..01ea6e7ac02 100644 --- a/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/models-autocomplete-open-chromium-linux.png +++ b/packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression/settings/models-autocomplete-open-chromium-linux.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e1a5dfe9704a74cbfa2da2a179ed995bcc31def156e798277dcfb568b25db58d -size 35913 +oid sha256:bbfed6606c5e1ccd6a744bdadf34ee597007d5f82c436c8c53e189560e0837d4 +size 30244 diff --git a/packages/kilo-gateway/package.json b/packages/kilo-gateway/package.json index c50a79a6df4..2ae78303918 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.3.12", + "version": "7.3.14", "type": "module", "license": "MIT", "description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration", @@ -50,8 +50,8 @@ "typescript": "catalog:", "@typescript/native-preview": "catalog:", "solid-js": "catalog:", - "@opentui/core": "0.1.75", - "@opentui/solid": "0.1.75" + "@opentui/core": "catalog:", + "@opentui/solid": "catalog:" }, "peerDependencies": { "solid-js": "*", diff --git a/packages/kilo-gateway/src/autocomplete.ts b/packages/kilo-gateway/src/autocomplete.ts index 356a19cc578..0d3a8e7b7b4 100644 --- a/packages/kilo-gateway/src/autocomplete.ts +++ b/packages/kilo-gateway/src/autocomplete.ts @@ -45,6 +45,19 @@ const models: AutocompleteModelDef[] = [ requestModel: "inception/mercury-edit-2", temperature: 0, }, + { + // Same wire-level model as `kilo/inception/mercury-edit-2`, but routed + // through the Kilo Gateway's Next Edit endpoint instead of FIM. Picked by + // users who want multi-line next-edit predictions with the jump-to-edit UX. + id: "kilo/inception/mercury-next-edit", + modelID: "inception/mercury-next-edit", + label: "Mercury Next Edit", + providerID: "kilo", + provider: "Kilo Gateway", + requestModel: "inception/mercury-edit-2", + temperature: 0, + kind: "edit", + }, { id: "mistral/codestral-2508", modelID: "codestral-2508", @@ -83,7 +96,20 @@ const models: AutocompleteModelDef[] = [ export const AUTOCOMPLETE_MODELS: readonly AutocompleteModelDef[] = models -export const DEFAULT_AUTOCOMPLETE_MODEL: AutocompleteModelDef = models[0]! +export const DEFAULT_AUTOCOMPLETE_PROVIDER_ID: AutocompleteProviderID = "kilo" +export const DEFAULT_AUTOCOMPLETE_MODEL_ID = "mistralai/codestral-2508" + +export const DEFAULT_AUTOCOMPLETE_MODEL: AutocompleteModelDef = (() => { + const found = models.find( + (m) => m.providerID === DEFAULT_AUTOCOMPLETE_PROVIDER_ID && m.modelID === DEFAULT_AUTOCOMPLETE_MODEL_ID, + ) + if (!found) { + throw new Error( + `DEFAULT_AUTOCOMPLETE_MODEL not found: provider=${DEFAULT_AUTOCOMPLETE_PROVIDER_ID} model=${DEFAULT_AUTOCOMPLETE_MODEL_ID}`, + ) + } + return found +})() const aliases: Record = { "inception/mercury-edit": "inception/mercury-edit-2", diff --git a/packages/kilo-gateway/src/edit.ts b/packages/kilo-gateway/src/edit.ts index 70151b01328..7740ced3f91 100644 --- a/packages/kilo-gateway/src/edit.ts +++ b/packages/kilo-gateway/src/edit.ts @@ -1,3 +1,4 @@ +import { KILO_API_BASE } from "./api/constants.js" import { getAutocompleteModel, type DirectAutocompleteProviderID } from "./autocomplete.js" /** @@ -20,20 +21,30 @@ export interface EditUpstreamResponse { } const INCEPTION_EDIT_URL = "https://api.inceptionlabs.ai/v1/edit/completions" +const KILO_NEXTEDIT_URL = KILO_API_BASE + "/api/edit/completions" /** - * Pick the upstream edit endpoint for a (provider, model) pair. Only Inception - * is wired up today — Mercury is the only model family with a documented - * /v1/edit/completions endpoint. Mistral does not expose a comparable surface. + * Pick the upstream edit endpoint for a (provider, model) pair. Today this is + * either Inception's `/v1/edit/completions` (direct BYOK) or the Kilo Gateway's + * `/api/edit/completions` proxy, which forwards to Inception server-side. + * Mistral does not expose a comparable surface. */ export function resolveEditTarget(provider?: string, model?: string): EditTarget { const info = getAutocompleteModel(provider, model) - if (info.kind === "edit" && info.directProvider === "inception") { - return { provider: "inception", model: info.requestModel, url: INCEPTION_EDIT_URL } + if (info.kind === "edit") { + if (info.providerID === "kilo") { + // The gateway expects the upstream model id with the `inception/` prefix + // (it strips it before forwarding to Inception). The kilo entry's + // `requestModel` already carries the prefix. + const m = info.requestModel.includes("/") ? info.requestModel : `inception/${info.requestModel}` + return { provider: "kilo", model: m, url: KILO_NEXTEDIT_URL } + } + if (info.directProvider === "inception") { + return { provider: "inception", model: info.requestModel, url: INCEPTION_EDIT_URL } + } } - // Kilo Gateway does not currently proxy an edit endpoint; callers should - // fall back to FIM. We still return a kilo target so the handler can surface - // a 400 rather than silently routing somewhere unexpected. + // Non-edit models fall through to a kilo placeholder with no URL so the + // handler can surface a 400 rather than silently routing somewhere unexpected. return { provider: "kilo", model: info.requestModel, url: "" } } diff --git a/packages/kilo-gateway/src/server/edit.ts b/packages/kilo-gateway/src/server/edit.ts index 5256881b238..fca7efa44e4 100644 --- a/packages/kilo-gateway/src/server/edit.ts +++ b/packages/kilo-gateway/src/server/edit.ts @@ -1,6 +1,8 @@ +import { HEADER_FEATURE } from "../api/constants.js" import { DIRECT_EDIT_ENV, extractFencedBody, resolveEditTarget, type EditTarget, type EditUpstreamResponse } from "../edit.js" import { buildMercuryEditPrompt, type MercuryEditContext } from "../edit-prompt.js" import type { DirectAutocompleteProviderID } from "../autocomplete.js" +import { buildKiloHeaders } from "../headers.js" import type { AuthStore } from "./handlers.js" type Auth = Pick @@ -14,16 +16,33 @@ async function getProviderKey(Auth: Auth, provider: DirectAutocompleteProviderID return DIRECT_EDIT_ENV[provider].map((key) => process.env[key]).find(Boolean) } +async function getProxyAuth(Auth: Auth) { + const auth = await Auth.get("kilo") + const token = auth?.type === "api" ? auth.key : auth?.type === "oauth" ? auth.access : undefined + return { + auth, + token, + organizationId: auth?.type === "oauth" ? auth.accountId : undefined, + } +} + export function createEditHandler(Auth: Auth) { return async (c: any) => { const { provider, model, maxTokens, ...context } = c.req.valid("json") const target = resolveEditTarget(provider, model) - if (target.provider !== "inception") { + if (target.provider === "kilo" && !target.url) { return c.json({ error: "Next Edit currently requires the Inception provider (mercury-edit-2)." }, 400 as any) } - const token = await getProviderKey(Auth, target.provider) + const proxy = target.provider === "kilo" ? await getProxyAuth(Auth) : undefined + const token = + target.provider === "kilo" ? proxy?.token : await getProviderKey(Auth, target.provider as DirectAutocompleteProviderID) + + if (target.provider === "kilo" && !proxy?.auth) { + return c.json({ error: "Not authenticated with Kilo Gateway" }, 401 as any) + } + if (!token) { return c.json({ error: `Missing ${target.provider} provider API key` }, 401 as any) } @@ -40,6 +59,10 @@ export function createEditHandler(Auth: Auth) { headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}`, + ...(target.provider === "kilo" + ? buildKiloHeaders(undefined, { kilocodeOrganizationId: proxy?.organizationId }) + : {}), + ...(target.provider === "kilo" ? { [HEADER_FEATURE]: "autocomplete" } : {}), }, signal, body: JSON.stringify({ diff --git a/packages/kilo-gateway/test/autocomplete.test.ts b/packages/kilo-gateway/test/autocomplete.test.ts new file mode 100644 index 00000000000..91ba6226b9d --- /dev/null +++ b/packages/kilo-gateway/test/autocomplete.test.ts @@ -0,0 +1,17 @@ +import { describe, expect, test } from "bun:test" +import { + AUTOCOMPLETE_MODELS, + DEFAULT_AUTOCOMPLETE_MODEL, + DEFAULT_AUTOCOMPLETE_MODEL_ID, + DEFAULT_AUTOCOMPLETE_PROVIDER_ID, +} from "../src/autocomplete" + +describe("DEFAULT_AUTOCOMPLETE_MODEL", () => { + test("resolves to an entry that exists in AUTOCOMPLETE_MODELS", () => { + const match = AUTOCOMPLETE_MODELS.find( + (m) => m.providerID === DEFAULT_AUTOCOMPLETE_PROVIDER_ID && m.modelID === DEFAULT_AUTOCOMPLETE_MODEL_ID, + ) + expect(match).toBeDefined() + expect(DEFAULT_AUTOCOMPLETE_MODEL).toBe(match!) + }) +}) diff --git a/packages/kilo-gateway/test/edit.test.ts b/packages/kilo-gateway/test/edit.test.ts index ba01ea163e8..0d240f70a88 100644 --- a/packages/kilo-gateway/test/edit.test.ts +++ b/packages/kilo-gateway/test/edit.test.ts @@ -16,6 +16,13 @@ describe("Edit target resolution", () => { expect(resolveEditTarget("inception", "mercury-edit-2").provider).toBe("kilo") }) + test("routes the Kilo Gateway next-edit model to the gateway proxy", () => { + const target = resolveEditTarget("kilo", "inception/mercury-next-edit") + expect(target.provider).toBe("kilo") + expect(target.model).toBe("inception/mercury-edit-2") + expect(target.url).toMatch(/\/api\/edit\/completions$/) + }) + test("falls back to a kilo placeholder (no upstream) for non-edit models", () => { expect(resolveEditTarget("kilo", "mistralai/codestral-2508")).toEqual({ provider: "kilo", diff --git a/packages/kilo-i18n/package.json b/packages/kilo-i18n/package.json index d4a38188187..60f171db8f8 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.3.12", + "version": "7.3.14", "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 d7a778caa65..87f1c525f82 100644 --- a/packages/kilo-i18n/src/ar.ts +++ b/packages/kilo-i18n/src/ar.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "المهارات", "marketplace.tab.mcpServers": "خوادم MCP", - "marketplace.tab.modes": "الأوضاع", "marketplace.category.all": "الكل", "marketplace.placeholder": "سيتم تنفيذه لاحقاً", "marketplace.card.installed": "مثبت", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "إلغاء", "marketplace.remove.confirm.button": "إزالة", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "وكلاء", "marketplace.search": "بحث...", "marketplace.filter.all": "جميع العناصر", "marketplace.filter.notInstalled": "غير مثبت", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "عام", "marketplace.remove.type.mcp": "خادم MCP", "marketplace.remove.type.skill": "مهارة", - "marketplace.remove.type.mode": "وضع", + "marketplace.remove.type.agent": "وكيل", "marketplace.remove.failed": "فشلت إزالة {{name}}", "marketplace.install": "تثبيت", "marketplace.filter.installed": "مثبت", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "عدة جلسات تعمل وستتوقف", "marketplace.warning.installAnyway": "تثبيت على أي حال", "marketplace.warning.cancel": "إلغاء", - "marketplace.contribute.prompt": "هل تفتقد مهارة أو وضعًا أو خادم MCP؟", + "marketplace.contribute.prompt": "هل تفتقد مهارة أو وكيلاً أو خادم MCP؟", "marketplace.contribute.cta": "ساهم على GitHub", + "marketplace.migration.notice": + "تم استبدال الأوضاع بالوكلاء. إذا كنت قد قمت بتثبيت أوضاع السوق سابقاً، يرجى إزالتها وإعادة تثبيتها كوكلاء للانتقال إلى التنسيق الجديد.", // Plan follow-up question shown after plan_exit "plan.followup.header": "نفّذ", diff --git a/packages/kilo-i18n/src/br.ts b/packages/kilo-i18n/src/br.ts index bbf53cd2ff3..21864df9338 100644 --- a/packages/kilo-i18n/src/br.ts +++ b/packages/kilo-i18n/src/br.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "Servidores MCP", - "marketplace.tab.modes": "Modos", "marketplace.category.all": "Todos", "marketplace.placeholder": "A ser implementado", "marketplace.card.installed": "Instalado", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Cancelar", "marketplace.remove.confirm.button": "Remover", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agentes", "marketplace.search": "Pesquisar...", "marketplace.filter.all": "Todos os Itens", "marketplace.filter.notInstalled": "Não Instalado", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "servidor MCP", "marketplace.remove.type.skill": "habilidade", - "marketplace.remove.type.mode": "modo", + "marketplace.remove.type.agent": "agente", "marketplace.remove.failed": "Falha ao remover {{name}}", "marketplace.install": "Instalar", "marketplace.filter.installed": "Instalado", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Várias sessões estão em execução e serão interrompidas", "marketplace.warning.installAnyway": "Instalar mesmo assim", "marketplace.warning.cancel": "Cancelar", - "marketplace.contribute.prompt": "Está faltando uma skill, modo ou servidor MCP?", + "marketplace.contribute.prompt": "Está faltando uma skill, agente ou servidor MCP?", "marketplace.contribute.cta": "Contribuir no GitHub", + "marketplace.migration.notice": + "Os modos foram substituídos por agentes. Se você instalou modos do marketplace anteriormente, remova-os e reinstale-os como agentes para migrar para o novo formato.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementar", diff --git a/packages/kilo-i18n/src/bs.ts b/packages/kilo-i18n/src/bs.ts index 2e4983260dc..e517c1352f2 100644 --- a/packages/kilo-i18n/src/bs.ts +++ b/packages/kilo-i18n/src/bs.ts @@ -24,7 +24,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Vještine", "marketplace.tab.mcpServers": "MCP Serveri", - "marketplace.tab.modes": "Modovi", "marketplace.category.all": "Sve", "marketplace.placeholder": "Biće implementirano", "marketplace.card.installed": "Instalirano", @@ -50,6 +49,7 @@ export const dict = { "marketplace.remove.cancel": "Otkaži", "marketplace.remove.confirm.button": "Ukloni", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenti", "marketplace.search": "Pretraži...", "marketplace.filter.all": "Sve stavke", "marketplace.filter.notInstalled": "Nije instalirano", @@ -65,7 +65,7 @@ export const dict = { "marketplace.scope.global": "globalno", "marketplace.remove.type.mcp": "MCP server", "marketplace.remove.type.skill": "vještina", - "marketplace.remove.type.mode": "režim", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Uklanjanje {{name}} nije uspjelo", "marketplace.install": "Instaliraj", "marketplace.filter.installed": "Instalirano", @@ -74,8 +74,10 @@ export const dict = { "marketplace.warning.busyMany": "Nekoliko sesija je pokrenuto i bit će prekinuto", "marketplace.warning.installAnyway": "Instaliraj svejedno", "marketplace.warning.cancel": "Otkaži", - "marketplace.contribute.prompt": "Nedostaje vještina, način rada ili MCP server?", + "marketplace.contribute.prompt": "Nedostaje vještina, agent ili MCP server?", "marketplace.contribute.cta": "Doprinesi na GitHub-u", + "marketplace.migration.notice": + "Modovi su zamijenjeni agentima. Ako ste prethodno instalirali marketplace modove, uklonite ih i ponovo instalirajte kao agente da biste prešli na novi format.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementiraj", diff --git a/packages/kilo-i18n/src/da.ts b/packages/kilo-i18n/src/da.ts index e930733acbe..b8189401bd6 100644 --- a/packages/kilo-i18n/src/da.ts +++ b/packages/kilo-i18n/src/da.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "MCP-servere", - "marketplace.tab.modes": "Tilstande", "marketplace.category.all": "Alle", "marketplace.placeholder": "Skal implementeres", "marketplace.card.installed": "Installeret", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Annuller", "marketplace.remove.confirm.button": "Fjern", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenter", "marketplace.search": "Søg...", "marketplace.filter.all": "Alle elementer", "marketplace.filter.notInstalled": "Ikke installeret", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "MCP-server", "marketplace.remove.type.skill": "færdighed", - "marketplace.remove.type.mode": "tilstand", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Kunne ikke fjerne {{name}}", "marketplace.install": "Installer", "marketplace.filter.installed": "Installeret", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Flere sessioner kører og vil blive afbrudt", "marketplace.warning.installAnyway": "Installer alligevel", "marketplace.warning.cancel": "Annuller", - "marketplace.contribute.prompt": "Mangler du en skill, tilstand eller MCP-server?", + "marketplace.contribute.prompt": "Mangler du en skill, agent eller MCP-server?", "marketplace.contribute.cta": "Bidrag på GitHub", + "marketplace.migration.notice": + "Tilstande er blevet erstattet af agenter. Hvis du tidligere har installeret marketplace-tilstande, skal du fjerne dem og geninstallere dem som agenter for at migrere til det nye format.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementér", diff --git a/packages/kilo-i18n/src/de.ts b/packages/kilo-i18n/src/de.ts index ce73601069b..a65837305ff 100644 --- a/packages/kilo-i18n/src/de.ts +++ b/packages/kilo-i18n/src/de.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "MCP-Server", - "marketplace.tab.modes": "Modi", "marketplace.category.all": "Alle", "marketplace.placeholder": "Noch nicht implementiert", "marketplace.card.installed": "Installiert", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Abbrechen", "marketplace.remove.confirm.button": "Entfernen", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenten", "marketplace.search": "Suchen...", "marketplace.filter.all": "Alle Elemente", "marketplace.filter.notInstalled": "Nicht installiert", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "Global", "marketplace.remove.type.mcp": "MCP-Server", "marketplace.remove.type.skill": "Skill", - "marketplace.remove.type.mode": "Modus", + "marketplace.remove.type.agent": "Agent", "marketplace.remove.failed": "Fehler beim Entfernen von {{name}}", "marketplace.install": "Installieren", "marketplace.filter.installed": "Installiert", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Mehrere Sitzungen laufen und werden unterbrochen", "marketplace.warning.installAnyway": "Trotzdem installieren", "marketplace.warning.cancel": "Abbrechen", - "marketplace.contribute.prompt": "Fehlt ein Skill, Modus oder MCP-Server?", + "marketplace.contribute.prompt": "Fehlt ein Skill, Agent oder MCP-Server?", "marketplace.contribute.cta": "Auf GitHub beitragen", + "marketplace.migration.notice": + "Modi wurden durch Agenten ersetzt. Wenn Sie zuvor Marketplace-Modi installiert haben, entfernen Sie diese bitte und installieren Sie sie als Agenten neu, um zum neuen Format zu migrieren.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Umsetzen", diff --git a/packages/kilo-i18n/src/en.ts b/packages/kilo-i18n/src/en.ts index 7f908032995..e2bc7de26d5 100644 --- a/packages/kilo-i18n/src/en.ts +++ b/packages/kilo-i18n/src/en.ts @@ -21,7 +21,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "MCP Servers", - "marketplace.tab.modes": "Modes", "marketplace.category.all": "All", "marketplace.placeholder": "To be implemented", "marketplace.card.installed": "Installed", @@ -47,6 +46,7 @@ export const dict = { "marketplace.remove.cancel": "Cancel", "marketplace.remove.confirm.button": "Remove", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agents", "marketplace.search": "Search...", "marketplace.filter.all": "All Items", "marketplace.filter.notInstalled": "Not Installed", @@ -62,7 +62,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "MCP server", "marketplace.remove.type.skill": "skill", - "marketplace.remove.type.mode": "mode", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Failed to remove {{name}}", "marketplace.install": "Install", "marketplace.filter.installed": "Installed", @@ -71,8 +71,10 @@ export const dict = { "marketplace.warning.busyMany": "Several sessions are running and will be interrupted", "marketplace.warning.installAnyway": "Install anyway", "marketplace.warning.cancel": "Cancel", - "marketplace.contribute.prompt": "Missing a skill, mode, or MCP server?", + "marketplace.contribute.prompt": "Missing a skill, agent, or MCP server?", "marketplace.contribute.cta": "Contribute on GitHub", + "marketplace.migration.notice": + "Modes have been replaced by agents. If you previously installed marketplace modes, please remove and reinstall them as agents to migrate to the new format.", // Plan follow-up question shown after plan_exit. The English strings here must match // the canonical `label`/`header`/`question` sent by the backend — those canonical labels diff --git a/packages/kilo-i18n/src/es.ts b/packages/kilo-i18n/src/es.ts index 07af68a1a0f..8312118c26a 100644 --- a/packages/kilo-i18n/src/es.ts +++ b/packages/kilo-i18n/src/es.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "Servidores MCP", - "marketplace.tab.modes": "Modos", "marketplace.category.all": "Todos", "marketplace.placeholder": "Por implementar", "marketplace.card.installed": "Instalado", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Cancelar", "marketplace.remove.confirm.button": "Eliminar", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agentes", "marketplace.search": "Buscar...", "marketplace.filter.all": "Todos los elementos", "marketplace.filter.notInstalled": "No instalado", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "servidor MCP", "marketplace.remove.type.skill": "habilidad", - "marketplace.remove.type.mode": "modo", + "marketplace.remove.type.agent": "agente", "marketplace.remove.failed": "Error al eliminar {{name}}", "marketplace.install": "Instalar", "marketplace.filter.installed": "Instalado", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Varias sesiones están en ejecución y se interrumpirán", "marketplace.warning.installAnyway": "Instalar de todas formas", "marketplace.warning.cancel": "Cancelar", - "marketplace.contribute.prompt": "¿Falta una skill, modo o servidor MCP?", + "marketplace.contribute.prompt": "¿Falta una skill, agente o servidor MCP?", "marketplace.contribute.cta": "Contribuir en GitHub", + "marketplace.migration.notice": + "Los modos han sido reemplazados por agentes. Si anteriormente instalaste modos del marketplace, elimínalos y reinstálalos como agentes para migrar al nuevo formato.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementar", diff --git a/packages/kilo-i18n/src/fr.ts b/packages/kilo-i18n/src/fr.ts index 2faf61d345b..510c0c7df91 100644 --- a/packages/kilo-i18n/src/fr.ts +++ b/packages/kilo-i18n/src/fr.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "Serveurs MCP", - "marketplace.tab.modes": "Modes", "marketplace.category.all": "Tout", "marketplace.placeholder": "À implémenter", "marketplace.card.installed": "Installé", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Annuler", "marketplace.remove.confirm.button": "Supprimer", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agents", "marketplace.search": "Rechercher...", "marketplace.filter.all": "Tous les éléments", "marketplace.filter.notInstalled": "Non installé", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "serveur MCP", "marketplace.remove.type.skill": "compétence", - "marketplace.remove.type.mode": "mode", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Échec de la suppression de {{name}}", "marketplace.install": "Installer", "marketplace.filter.installed": "Installé", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Plusieurs sessions sont en cours et seront interrompues", "marketplace.warning.installAnyway": "Installer quand même", "marketplace.warning.cancel": "Annuler", - "marketplace.contribute.prompt": "Il manque une skill, un mode ou un serveur MCP ?", + "marketplace.contribute.prompt": "Il manque une compétence, un agent ou un serveur MCP ?", "marketplace.contribute.cta": "Contribuer sur GitHub", + "marketplace.migration.notice": + "Les modes ont été remplacés par des agents. Si vous avez précédemment installé des modes depuis le marketplace, veuillez les supprimer et les réinstaller en tant qu'agents pour migrer vers le nouveau format.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implémenter", diff --git a/packages/kilo-i18n/src/ja.ts b/packages/kilo-i18n/src/ja.ts index f30eae15557..634e4729604 100644 --- a/packages/kilo-i18n/src/ja.ts +++ b/packages/kilo-i18n/src/ja.ts @@ -18,7 +18,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "スキル", "marketplace.tab.mcpServers": "MCPサーバー", - "marketplace.tab.modes": "モード", "marketplace.category.all": "すべて", "marketplace.placeholder": "未実装", "marketplace.card.installed": "インストール済み", @@ -43,6 +42,7 @@ export const dict = { "marketplace.remove.cancel": "キャンセル", "marketplace.remove.confirm.button": "削除", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "エージェント", "marketplace.search": "検索...", "marketplace.filter.all": "すべてのアイテム", "marketplace.filter.notInstalled": "未インストール", @@ -58,7 +58,7 @@ export const dict = { "marketplace.scope.global": "グローバル", "marketplace.remove.type.mcp": "MCPサーバー", "marketplace.remove.type.skill": "スキル", - "marketplace.remove.type.mode": "モード", + "marketplace.remove.type.agent": "エージェント", "marketplace.remove.failed": "{{name}} の削除に失敗しました", "marketplace.install": "インストール", "marketplace.filter.installed": "インストール済み", @@ -67,8 +67,10 @@ export const dict = { "marketplace.warning.busyMany": "複数のセッションが実行中で中断されます", "marketplace.warning.installAnyway": "それでもインストール", "marketplace.warning.cancel": "キャンセル", - "marketplace.contribute.prompt": "スキル、モード、MCP サーバーが見つかりませんか?", + "marketplace.contribute.prompt": "スキル、エージェント、またはMCPサーバーが見つかりませんか?", "marketplace.contribute.cta": "GitHub で貢献する", + "marketplace.migration.notice": + "モードはエージェントに置き換えられました。以前にマーケットプレイスのモードをインストールしていた場合は、新しい形式に移行するためにそれらを削除してエージェントとして再インストールしてください。", // Plan follow-up question shown after plan_exit "plan.followup.header": "実装", diff --git a/packages/kilo-i18n/src/ko.ts b/packages/kilo-i18n/src/ko.ts index 8a9692001fe..1e3c37ee0f5 100644 --- a/packages/kilo-i18n/src/ko.ts +++ b/packages/kilo-i18n/src/ko.ts @@ -18,7 +18,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "스킬", "marketplace.tab.mcpServers": "MCP 서버", - "marketplace.tab.modes": "모드", "marketplace.category.all": "전체", "marketplace.placeholder": "구현 예정", "marketplace.card.installed": "설치됨", @@ -43,6 +42,7 @@ export const dict = { "marketplace.remove.cancel": "취소", "marketplace.remove.confirm.button": "제거", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "에이전트", "marketplace.search": "검색...", "marketplace.filter.all": "모든 항목", "marketplace.filter.notInstalled": "설치되지 않음", @@ -58,7 +58,7 @@ export const dict = { "marketplace.scope.global": "글로벌", "marketplace.remove.type.mcp": "MCP 서버", "marketplace.remove.type.skill": "스킬", - "marketplace.remove.type.mode": "모드", + "marketplace.remove.type.agent": "에이전트", "marketplace.remove.failed": "{{name}} 제거 실패", "marketplace.install": "설치", "marketplace.filter.installed": "설치됨", @@ -67,8 +67,10 @@ export const dict = { "marketplace.warning.busyMany": "여러 세션이 실행 중이며 중단됩니다", "marketplace.warning.installAnyway": "그래도 설치", "marketplace.warning.cancel": "취소", - "marketplace.contribute.prompt": "스킬, 모드 또는 MCP 서버가 없나요?", + "marketplace.contribute.prompt": "스킬, 에이전트 또는 MCP 서버가 없나요?", "marketplace.contribute.cta": "GitHub에서 기여하기", + "marketplace.migration.notice": + "모드가 에이전트로 대체되었습니다. 이전에 마켓플레이스 모드를 설치한 경우 새 형식으로 마이그레이션하려면 해당 모드를 제거하고 에이전트로 다시 설치하세요.", // Plan follow-up question shown after plan_exit "plan.followup.header": "구현", diff --git a/packages/kilo-i18n/src/nl.ts b/packages/kilo-i18n/src/nl.ts index 142c0958286..3e42fb7abff 100644 --- a/packages/kilo-i18n/src/nl.ts +++ b/packages/kilo-i18n/src/nl.ts @@ -21,7 +21,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "MCP Servers", - "marketplace.tab.modes": "Modi", "marketplace.category.all": "Alle", "marketplace.placeholder": "Nog te implementeren", "marketplace.card.installed": "Geïnstalleerd", @@ -47,6 +46,7 @@ export const dict = { "marketplace.remove.cancel": "Annuleren", "marketplace.remove.confirm.button": "Verwijderen", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenten", "marketplace.search": "Zoeken...", "marketplace.filter.all": "Alle items", "marketplace.filter.notInstalled": "Niet geïnstalleerd", @@ -62,7 +62,7 @@ export const dict = { "marketplace.scope.global": "globaal", "marketplace.remove.type.mcp": "MCP server", "marketplace.remove.type.skill": "skill", - "marketplace.remove.type.mode": "modus", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Verwijderen van {{name}} mislukt", "marketplace.install": "Installeren", "marketplace.filter.installed": "Geïnstalleerd", @@ -71,8 +71,10 @@ export const dict = { "marketplace.warning.busyMany": "Er zijn meerdere sessies actief en deze zullen worden onderbroken", "marketplace.warning.installAnyway": "Toch installeren", "marketplace.warning.cancel": "Annuleren", - "marketplace.contribute.prompt": "Mist er een skill, modus of MCP-server?", + "marketplace.contribute.prompt": "Mist u een skill, agent of MCP-server?", "marketplace.contribute.cta": "Bijdragen op GitHub", + "marketplace.migration.notice": + "Modi zijn vervangen door agenten. Als u eerder marketplace-modi hebt geïnstalleerd, verwijder ze dan en installeer ze opnieuw als agenten om naar het nieuwe formaat te migreren.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementeren", diff --git a/packages/kilo-i18n/src/no.ts b/packages/kilo-i18n/src/no.ts index e7f223b923b..c23bf6c3e84 100644 --- a/packages/kilo-i18n/src/no.ts +++ b/packages/kilo-i18n/src/no.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "MCP-servere", - "marketplace.tab.modes": "Moduser", "marketplace.category.all": "Alle", "marketplace.placeholder": "Skal implementeres", "marketplace.card.installed": "Installert", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Avbryt", "marketplace.remove.confirm.button": "Fjern", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenter", "marketplace.search": "Søk...", "marketplace.filter.all": "Alle elementer", "marketplace.filter.notInstalled": "Ikke installert", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "global", "marketplace.remove.type.mcp": "MCP-server", "marketplace.remove.type.skill": "ferdighet", - "marketplace.remove.type.mode": "modus", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Kunne ikke fjerne {{name}}", "marketplace.install": "Installer", "marketplace.filter.installed": "Installert", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Flere økter kjører og vil bli avbrutt", "marketplace.warning.installAnyway": "Installer uansett", "marketplace.warning.cancel": "Avbryt", - "marketplace.contribute.prompt": "Mangler du en skill, modus eller MCP-server?", + "marketplace.contribute.prompt": "Mangler du en skill, agent eller MCP-server?", "marketplace.contribute.cta": "Bidra på GitHub", + "marketplace.migration.notice": + "Modi er erstattet av agenter. Hvis du tidligere har installert marketplace-modi, fjern dem og installer dem på nytt som agenter for å migrere til det nye formatet.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Implementer", diff --git a/packages/kilo-i18n/src/pl.ts b/packages/kilo-i18n/src/pl.ts index 8cfd61e3c2b..09cbe56e59b 100644 --- a/packages/kilo-i18n/src/pl.ts +++ b/packages/kilo-i18n/src/pl.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Skills", "marketplace.tab.mcpServers": "Serwery MCP", - "marketplace.tab.modes": "Tryby", "marketplace.category.all": "Wszystkie", "marketplace.placeholder": "Do zaimplementowania", "marketplace.card.installed": "Zainstalowano", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Anuluj", "marketplace.remove.confirm.button": "Usuń", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Agenci", "marketplace.search": "Szukaj...", "marketplace.filter.all": "Wszystkie elementy", "marketplace.filter.notInstalled": "Nie zainstalowano", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "globalny", "marketplace.remove.type.mcp": "serwer MCP", "marketplace.remove.type.skill": "umiejętność", - "marketplace.remove.type.mode": "tryb", + "marketplace.remove.type.agent": "agent", "marketplace.remove.failed": "Nie udało się usunąć {{name}}", "marketplace.install": "Zainstaluj", "marketplace.filter.installed": "Zainstalowano", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Kilka sesji jest uruchomionych i zostanie przerwanych", "marketplace.warning.installAnyway": "Zainstaluj mimo to", "marketplace.warning.cancel": "Anuluj", - "marketplace.contribute.prompt": "Brakuje skilla, trybu lub serwera MCP?", + "marketplace.contribute.prompt": "Brakuje umiejętności, agenta lub serwera MCP?", "marketplace.contribute.cta": "Wnieś wkład na GitHubie", + "marketplace.migration.notice": + "Tryby zostały zastąpione przez agentów. Jeśli wcześniej instalowałeś tryby z marketplace, usuń je i zainstaluj ponownie jako agenty, aby przejść na nowy format.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Wdróż", diff --git a/packages/kilo-i18n/src/ru.ts b/packages/kilo-i18n/src/ru.ts index 2a923436c22..89dc4e409b6 100644 --- a/packages/kilo-i18n/src/ru.ts +++ b/packages/kilo-i18n/src/ru.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Навыки", "marketplace.tab.mcpServers": "MCP-серверы", - "marketplace.tab.modes": "Режимы", "marketplace.category.all": "Все", "marketplace.placeholder": "Будет реализовано", "marketplace.card.installed": "Установлено", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Отмена", "marketplace.remove.confirm.button": "Удалить", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Агенты", "marketplace.search": "Поиск...", "marketplace.filter.all": "Все элементы", "marketplace.filter.notInstalled": "Не установлено", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "глобально", "marketplace.remove.type.mcp": "MCP-сервер", "marketplace.remove.type.skill": "навык", - "marketplace.remove.type.mode": "режим", + "marketplace.remove.type.agent": "агент", "marketplace.remove.failed": "Не удалось удалить {{name}}", "marketplace.install": "Установить", "marketplace.filter.installed": "Установлено", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Несколько сеансов выполняются и будут прерваны", "marketplace.warning.installAnyway": "Установить в любом случае", "marketplace.warning.cancel": "Отмена", - "marketplace.contribute.prompt": "Не хватает навыка, режима или MCP-сервера?", + "marketplace.contribute.prompt": "Не хватает навыка, агента или MCP-сервера?", "marketplace.contribute.cta": "Внести вклад на GitHub", + "marketplace.migration.notice": + "Режимы заменены агентами. Если вы ранее устанавливали режимы из магазина, удалите их и переустановите как агенты, чтобы перейти на новый формат.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Реализовать", diff --git a/packages/kilo-i18n/src/th.ts b/packages/kilo-i18n/src/th.ts index ae0c5a4d88c..8affeb54c16 100644 --- a/packages/kilo-i18n/src/th.ts +++ b/packages/kilo-i18n/src/th.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "ทักษะ", "marketplace.tab.mcpServers": "เซิร์ฟเวอร์ MCP", - "marketplace.tab.modes": "โหมด", "marketplace.category.all": "ทั้งหมด", "marketplace.placeholder": "ยังไม่ได้ดำเนินการ", "marketplace.card.installed": "ติดตั้งแล้ว", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "ยกเลิก", "marketplace.remove.confirm.button": "ลบ", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "เอเจนต์", "marketplace.search": "ค้นหา...", "marketplace.filter.all": "รายการทั้งหมด", "marketplace.filter.notInstalled": "ยังไม่ได้ติดตั้ง", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "โกลบอล", "marketplace.remove.type.mcp": "เซิร์ฟเวอร์ MCP", "marketplace.remove.type.skill": "ทักษะ", - "marketplace.remove.type.mode": "โหมด", + "marketplace.remove.type.agent": "เอเจนต์", "marketplace.remove.failed": "ไม่สามารถลบ {{name}} ได้", "marketplace.install": "ติดตั้ง", "marketplace.filter.installed": "ติดตั้งแล้ว", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "มีหลายเซสชันกำลังทำงานและจะถูกขัดจังหวะ", "marketplace.warning.installAnyway": "ติดตั้งต่อไป", "marketplace.warning.cancel": "ยกเลิก", - "marketplace.contribute.prompt": "ไม่พบทักษะ โหมด หรือเซิร์ฟเวอร์ MCP ที่ต้องการ?", + "marketplace.contribute.prompt": "ขาดสกิล เอเจนต์ หรือเซิร์ฟเวอร์ MCP?", "marketplace.contribute.cta": "ร่วมสมทบบน GitHub", + "marketplace.migration.notice": + "โหมดถูกแทนที่ด้วยเอเจนต์แล้ว หากคุณเคยติดตั้งโหมดจาก marketplace กรุณาลบและติดตั้งใหม่เป็นเอเจนต์เพื่อย้ายไปยังรูปแบบใหม่", // Plan follow-up question shown after plan_exit "plan.followup.header": "ดำเนินการ", diff --git a/packages/kilo-i18n/src/tr.ts b/packages/kilo-i18n/src/tr.ts index 6297ed3295a..b4e335f0501 100644 --- a/packages/kilo-i18n/src/tr.ts +++ b/packages/kilo-i18n/src/tr.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Yetenekler", "marketplace.tab.mcpServers": "MCP Sunucuları", - "marketplace.tab.modes": "Modlar", "marketplace.category.all": "Tümü", "marketplace.placeholder": "Uygulanacak", "marketplace.card.installed": "Yüklendi", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "İptal", "marketplace.remove.confirm.button": "Kaldır", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Ajanlar", "marketplace.search": "Ara...", "marketplace.filter.all": "Tüm Öğeler", "marketplace.filter.notInstalled": "Yüklü Değil", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "genel", "marketplace.remove.type.mcp": "MCP sunucusu", "marketplace.remove.type.skill": "yetenek", - "marketplace.remove.type.mode": "mod", + "marketplace.remove.type.agent": "ajan", "marketplace.remove.failed": "{{name}} kaldırılamadı", "marketplace.install": "Yükle", "marketplace.filter.installed": "Yüklendi", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Birden fazla oturum çalışıyor ve kesintiye uğrayacak", "marketplace.warning.installAnyway": "Yine de yükle", "marketplace.warning.cancel": "İptal", - "marketplace.contribute.prompt": "Bir yetenek, mod veya MCP sunucusu mu eksik?", + "marketplace.contribute.prompt": "Bir yetenek, ajan veya MCP sunucusu mu eksik?", "marketplace.contribute.cta": "GitHub'da katkıda bulun", + "marketplace.migration.notice": + "Modlar agentlarla değiştirildi. Daha önce marketplace modları yüklediyseniz, yeni formata geçiş yapmak için bunları kaldırın ve agent olarak yeniden yükleyin.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Uygula", diff --git a/packages/kilo-i18n/src/uk.ts b/packages/kilo-i18n/src/uk.ts index afc11ae14e1..795fd1398bc 100644 --- a/packages/kilo-i18n/src/uk.ts +++ b/packages/kilo-i18n/src/uk.ts @@ -19,7 +19,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "Навички", "marketplace.tab.mcpServers": "MCP-сервери", - "marketplace.tab.modes": "Режими", "marketplace.category.all": "Усі", "marketplace.placeholder": "Буде реалізовано", "marketplace.card.installed": "Встановлено", @@ -45,6 +44,7 @@ export const dict = { "marketplace.remove.cancel": "Скасувати", "marketplace.remove.confirm.button": "Видалити", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "Агенти", "marketplace.search": "Пошук...", "marketplace.filter.all": "Усі елементи", "marketplace.filter.notInstalled": "Не встановлено", @@ -60,7 +60,7 @@ export const dict = { "marketplace.scope.global": "глобально", "marketplace.remove.type.mcp": "MCP-сервер", "marketplace.remove.type.skill": "навичка", - "marketplace.remove.type.mode": "режим", + "marketplace.remove.type.agent": "агент", "marketplace.remove.failed": "Не вдалося видалити {{name}}", "marketplace.install": "Встановити", "marketplace.filter.installed": "Встановлено", @@ -69,8 +69,10 @@ export const dict = { "marketplace.warning.busyMany": "Виконується кілька сесій, їх буде перервано", "marketplace.warning.installAnyway": "Встановити все одно", "marketplace.warning.cancel": "Скасувати", - "marketplace.contribute.prompt": "Бракує навички, режиму або MCP-сервера?", + "marketplace.contribute.prompt": "Бракує навички, агента або MCP-сервера?", "marketplace.contribute.cta": "Зробити внесок на GitHub", + "marketplace.migration.notice": + "Режими замінено агентами. Якщо ви раніше встановлювали режими з маркетплейсу, видаліть їх та перевстановіть як агенти для переходу на новий формат.", // Plan follow-up question shown after plan_exit "plan.followup.header": "Реалізувати", diff --git a/packages/kilo-i18n/src/zh.ts b/packages/kilo-i18n/src/zh.ts index 37954ff59d2..f23fbb9c66a 100644 --- a/packages/kilo-i18n/src/zh.ts +++ b/packages/kilo-i18n/src/zh.ts @@ -17,7 +17,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "技能", "marketplace.tab.mcpServers": "MCP 服务器", - "marketplace.tab.modes": "模式", "marketplace.category.all": "全部", "marketplace.placeholder": "待实现", "marketplace.card.installed": "已安装", @@ -42,6 +41,7 @@ export const dict = { "marketplace.remove.cancel": "取消", "marketplace.remove.confirm.button": "移除", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "智能体", "marketplace.search": "搜索...", "marketplace.filter.all": "所有项目", "marketplace.filter.notInstalled": "未安装", @@ -57,7 +57,7 @@ export const dict = { "marketplace.scope.global": "全局", "marketplace.remove.type.mcp": "MCP 服务器", "marketplace.remove.type.skill": "技能", - "marketplace.remove.type.mode": "模式", + "marketplace.remove.type.agent": "智能体", "marketplace.remove.failed": "移除 {{name}} 失败", "marketplace.install": "安装", "marketplace.filter.installed": "已安装", @@ -66,8 +66,10 @@ export const dict = { "marketplace.warning.busyMany": "多个会话正在运行,将被中断", "marketplace.warning.installAnyway": "仍然安装", "marketplace.warning.cancel": "取消", - "marketplace.contribute.prompt": "缺少技能、模式或 MCP 服务器?", + "marketplace.contribute.prompt": "缺少技能、智能体或 MCP 服务器?", "marketplace.contribute.cta": "在 GitHub 上贡献", + "marketplace.migration.notice": + "模式已被智能体取代。如果您之前安装了市场中的模式,请将其删除并重新安装为智能体,以迁移到新格式。", // Plan follow-up question shown after plan_exit "plan.followup.header": "实现", diff --git a/packages/kilo-i18n/src/zht.ts b/packages/kilo-i18n/src/zht.ts index 5561173b89d..930ddcf3ac5 100644 --- a/packages/kilo-i18n/src/zht.ts +++ b/packages/kilo-i18n/src/zht.ts @@ -17,7 +17,6 @@ export const dict = { // Marketplace "marketplace.tab.skills": "技能", "marketplace.tab.mcpServers": "MCP 伺服器", - "marketplace.tab.modes": "模式", "marketplace.category.all": "全部", "marketplace.placeholder": "待實作", "marketplace.card.installed": "已安裝", @@ -42,6 +41,7 @@ export const dict = { "marketplace.remove.cancel": "取消", "marketplace.remove.confirm.button": "移除", "marketplace.tab.mcp": "MCP", + "marketplace.tab.agents": "智能體", "marketplace.search": "搜尋...", "marketplace.filter.all": "所有項目", "marketplace.filter.notInstalled": "未安裝", @@ -57,7 +57,7 @@ export const dict = { "marketplace.scope.global": "全域", "marketplace.remove.type.mcp": "MCP 伺服器", "marketplace.remove.type.skill": "技能", - "marketplace.remove.type.mode": "模式", + "marketplace.remove.type.agent": "智能體", "marketplace.remove.failed": "移除 {{name}} 失敗", "marketplace.install": "安裝", "marketplace.filter.installed": "已安裝", @@ -66,8 +66,10 @@ export const dict = { "marketplace.warning.busyMany": "多個工作階段正在執行,將被中斷", "marketplace.warning.installAnyway": "仍然安裝", "marketplace.warning.cancel": "取消", - "marketplace.contribute.prompt": "缺少技能、模式或 MCP 伺服器?", + "marketplace.contribute.prompt": "缺少技能、智能體或 MCP 伺服器?", "marketplace.contribute.cta": "在 GitHub 上貢獻", + "marketplace.migration.notice": + "模式已被智能體取代。如果您之前安裝了市場中的模式,請將其刪除並重新安裝為智能體,以遷移到新格式。", // Plan follow-up question shown after plan_exit "plan.followup.header": "實作", diff --git a/packages/kilo-indexing/package.json b/packages/kilo-indexing/package.json index 479f7b7dfe2..be0f68487af 100644 --- a/packages/kilo-indexing/package.json +++ b/packages/kilo-indexing/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@kilocode/kilo-indexing", - "version": "7.3.12", + "version": "7.3.14", "type": "module", "license": "MIT", "description": "Standalone indexing engine and host helpers for Kilo Code", diff --git a/packages/kilo-indexing/src/config.ts b/packages/kilo-indexing/src/config.ts index 8eae226e0ca..a4477388036 100644 --- a/packages/kilo-indexing/src/config.ts +++ b/packages/kilo-indexing/src/config.ts @@ -21,11 +21,12 @@ export const IndexingConfig = z .object({ enabled: z.boolean().optional().describe("Enable codebase indexing"), provider: z.enum(providers).optional().describe("Embedding provider to use for codebase indexing"), - model: z.string().optional().describe("Embedding model ID (uses provider default if omitted)"), + model: z.string().nullable().optional().describe("Embedding model ID (uses provider default if omitted)"), dimension: z .number() .int() .positive() + .nullable() .optional() .describe("Override embedding vector dimension (auto-detected from model if omitted)"), vectorStore: z.enum(stores).optional().describe("Vector store backend (default: qdrant)"), @@ -140,10 +141,10 @@ export const IndexingSchema = Schema.Struct({ provider: Schema.optional(Provider).annotate({ description: "Embedding provider to use for codebase indexing", }), - model: Schema.optional(Schema.String).annotate({ + model: Schema.optional(Schema.NullOr(Schema.String)).annotate({ description: "Embedding model ID (uses provider default if omitted)", }), - dimension: Schema.optional(PositiveInt).annotate({ + dimension: Schema.optional(Schema.NullOr(PositiveInt)).annotate({ description: "Override embedding vector dimension (auto-detected from model if omitted)", }), vectorStore: Schema.optional(Store).annotate({ description: "Vector store backend (default: qdrant)" }), @@ -237,8 +238,8 @@ export function toIndexingConfigInput(cfg: IndexingConfig | undefined): Indexing enabled: cfg?.enabled ?? false, embedderProvider: provider, vectorStoreProvider: cfg?.vectorStore, - modelId: cfg?.model, - modelDimension: cfg?.dimension, + modelId: cfg?.model ?? undefined, + modelDimension: cfg?.dimension ?? undefined, lancedbVectorStoreDirectory: cfg?.lancedb?.directory, qdrantUrl: cfg?.qdrant?.url, qdrantApiKey: cfg?.qdrant?.apiKey, diff --git a/packages/kilo-jetbrains/package.json b/packages/kilo-jetbrains/package.json index 3023fc9876a..00391a208fb 100644 --- a/packages/kilo-jetbrains/package.json +++ b/packages/kilo-jetbrains/package.json @@ -8,7 +8,7 @@ "test": "./gradlew test", "test:ci": "bun script/test-ci.ts" }, - "version": "7.3.12", + "version": "7.3.14", "dependencies": {}, "devDependencies": {}, "peerDependencies": {} diff --git a/packages/kilo-telemetry/package.json b/packages/kilo-telemetry/package.json index 8cb18274952..6a135baff37 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.3.12", + "version": "7.3.14", "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 454e6768ad7..90c08b0589d 100644 --- a/packages/kilo-ui/package.json +++ b/packages/kilo-ui/package.json @@ -1,6 +1,6 @@ { "name": "@kilocode/kilo-ui", - "version": "7.3.12", + "version": "7.3.14", "type": "module", "license": "MIT", "exports": { diff --git a/packages/kilo-ui/src/components/card.css b/packages/kilo-ui/src/components/card.css index 6ae4d7d2693..360d1028608 100644 --- a/packages/kilo-ui/src/components/card.css +++ b/packages/kilo-ui/src/components/card.css @@ -5,6 +5,13 @@ padding: 8px; border: 1px solid var(--border-weak-base); + &[data-variant="error"] { + padding: 12px; + background-color: color-mix(in srgb, var(--surface-critical-strong) 10%, var(--surface-inset-base)); + border-color: color-mix(in srgb, var(--border-critical-selected) 55%, var(--border-weaker-base)); + color: var(--text-base); + } + &[data-variant="warning"] { padding: 12px 14px; } diff --git a/packages/kilo-ui/src/components/error-details.css b/packages/kilo-ui/src/components/error-details.css index 259150984e0..88f97120a2e 100644 --- a/packages/kilo-ui/src/components/error-details.css +++ b/packages/kilo-ui/src/components/error-details.css @@ -1,42 +1,92 @@ .error-card { - padding-bottom: 0; - background-color: var(--surface-critical-base); + gap: 8px; + padding-bottom: 12px; + --error-card-accent: var(--text-on-critical-base); +} + +.error-card-body { + display: flex; + align-items: flex-start; + gap: 8px; +} + +.error-card-body [data-component="icon"] { + color: var(--error-card-accent); + margin-top: 2px; +} + +.error-card-message { + flex: 1; + min-width: 0; + color: var(--text-strong); + font-size: var(--font-size-base); + line-height: var(--line-height-large); + overflow-wrap: anywhere; } .error-card [data-component="collapsible"] { - margin-top: 8px; + margin-top: 0; + padding-left: 24px; } -.error-details-trigger { +.error-card .error-details-trigger[data-slot="collapsible-trigger"] { display: inline-flex; align-items: center; - gap: 4px; + align-self: flex-start; + gap: 2px; + width: auto; + height: 22px; font-size: var(--font-size-small); + font-weight: var(--font-weight-medium); opacity: 0.85; cursor: pointer; background: none; border: none; - color: inherit; - padding: 0; + border-radius: var(--radius-sm); + color: var(--error-card-accent); + padding: 0 6px; } -.error-details-trigger:hover { +.error-card .error-details-trigger[data-slot="collapsible-trigger"]:hover { + background-color: color-mix(in srgb, var(--error-card-accent) 12%, transparent); opacity: 1; } +.error-card .error-details-trigger[data-slot="collapsible-trigger"]:focus-visible { + background-color: color-mix(in srgb, var(--error-card-accent) 12%, transparent); + outline: 1px solid var(--border-focus); + outline-offset: 2px; +} + +.error-card .error-details-trigger [data-slot="collapsible-arrow"] { + width: 16px; + height: 16px; + opacity: 1; +} + +.error-card .error-details-trigger [data-slot="collapsible-arrow-icon"] { + color: currentColor; +} + .error-details { display: flex; flex-direction: column; - gap: 4px; + gap: 6px; font-size: var(--font-size-small); - margin-top: 4px; + margin-top: 8px; } .error-detail-pre { margin: 0; max-height: 120px; overflow-y: auto; + background-color: color-mix(in srgb, var(--surface-inset-base) 82%, var(--background-base)); + border: 1px solid color-mix(in srgb, var(--border-critical-base) 30%, var(--border-weaker-base)); + border-radius: var(--radius-sm); + color: var(--text-base); font-size: var(--font-size-small); + line-height: var(--line-height-large); + padding: 8px; white-space: pre-wrap; word-break: break-all; flex: 1; diff --git a/packages/kilo-ui/src/components/error-details.tsx b/packages/kilo-ui/src/components/error-details.tsx index c720bd80f8c..1a306385865 100644 --- a/packages/kilo-ui/src/components/error-details.tsx +++ b/packages/kilo-ui/src/components/error-details.tsx @@ -11,7 +11,7 @@ export function ErrorDetails(props: ErrorDetailsProps) { return (
-
{raw()}
+
{raw()}
) } diff --git a/packages/kilo-ui/src/pierre/index.ts b/packages/kilo-ui/src/pierre/index.ts index 20b1ad7fd1c..0d2edfeea93 100644 --- a/packages/kilo-ui/src/pierre/index.ts +++ b/packages/kilo-ui/src/pierre/index.ts @@ -6,8 +6,38 @@ import { type SelectedLineRange, } from "@pierre/diffs" import { ComponentProps } from "solid-js" +import { createDefaultOptions as defaults, styleVariables } from "@opencode-ai/ui/pierre" -export { createDefaultOptions, styleVariables } from "@opencode-ai/ui/pierre" +export { styleVariables } + +// Pierre 1.1 treats its changed-line override properties as tint targets. Apply +// Kilo semantic surfaces at the computed row level so host diff colors stay final. +const css = ` +[data-diff][data-background] [data-line][data-line-type='change-addition'] { + --diffs-computed-diff-line-bg: var(--surface-diff-add-base, var(--diffs-bg-addition)); + --diffs-computed-selected-line-bg: var(--surface-diff-add-base, var(--diffs-bg-addition)); +} +[data-diff][data-background] [data-column-number][data-line-type='change-addition'] { + --diffs-computed-diff-line-bg: var(--surface-diff-add-weaker, var(--diffs-bg-addition-number)); + --diffs-computed-selected-line-bg: var(--surface-diff-add-weaker, var(--diffs-bg-addition-number)); +} +[data-diff][data-background] [data-line][data-line-type='change-deletion'] { + --diffs-computed-diff-line-bg: var(--surface-diff-delete-base, var(--diffs-bg-deletion)); + --diffs-computed-selected-line-bg: var(--surface-diff-delete-base, var(--diffs-bg-deletion)); +} +[data-diff][data-background] [data-column-number][data-line-type='change-deletion'] { + --diffs-computed-diff-line-bg: var(--surface-diff-delete-weaker, var(--diffs-bg-deletion-number)); + --diffs-computed-selected-line-bg: var(--surface-diff-delete-weaker, var(--diffs-bg-deletion-number)); +} +` + +export function createDefaultOptions(style: FileDiffOptions["diffStyle"]) { + const opts = defaults(style) + return { + ...opts, + unsafeCSS: `${opts.unsafeCSS}\n${css}`, + } +} // Extends upstream DiffProps with a `fileDiff` variant so Pierre can render // a precomputed FileDiffMetadata directly. The pair (before/after) variant diff --git a/packages/kilo-ui/src/styles/vscode-bridge.css b/packages/kilo-ui/src/styles/vscode-bridge.css index 5ad8a6a6920..f73537c5c38 100644 --- a/packages/kilo-ui/src/styles/vscode-bridge.css +++ b/packages/kilo-ui/src/styles/vscode-bridge.css @@ -68,7 +68,7 @@ html[data-theme="kilo-vscode"] { --surface-critical-base: var(--vscode-editorMarkerNavigationError-headerBackground); --surface-critical-weak: var(--vscode-editorMarkerNavigationError-headerBackground); - --surface-critical-strong: var(--vscode-charts-red); + --surface-critical-strong: var(--vscode-errorForeground, var(--vscode-charts-red)); --surface-info-base: var(--vscode-editorMarkerNavigationInfo-headerBackground); --surface-info-weak: var(--vscode-editorMarkerNavigationInfo-headerBackground); @@ -76,13 +76,22 @@ html[data-theme="kilo-vscode"] { /* Diff surfaces */ --surface-diff-unchanged-base: var(--vscode-editor-background); - --surface-diff-skip-base: var(--vscode-diffEditor-unchangedCodeBackground); + --surface-diff-skip-base: var( + --vscode-diffEditor-unchangedRegionBackground, + var(--vscode-diffEditor-unchangedCodeBackground, var(--vscode-editor-background)) + ); --surface-diff-add-base: var(--vscode-diffEditor-insertedLineBackground); --surface-diff-add-weak: var(--vscode-diffEditor-insertedTextBackground); - --surface-diff-add-weaker: var(--vscode-diffEditor-insertedLineBackground); + --surface-diff-add-weaker: var( + --vscode-diffEditorGutter-insertedLineBackground, + var(--vscode-diffEditor-insertedLineBackground) + ); --surface-diff-delete-base: var(--vscode-diffEditor-removedLineBackground); --surface-diff-delete-weak: var(--vscode-diffEditor-removedTextBackground); - --surface-diff-delete-weaker: var(--vscode-diffEditor-removedLineBackground); + --surface-diff-delete-weaker: var( + --vscode-diffEditorGutter-removedLineBackground, + var(--vscode-diffEditor-removedLineBackground) + ); /* ===== Inputs ===== */ --input-base: var(--vscode-input-background); @@ -116,9 +125,9 @@ html[data-theme="kilo-vscode"] { --text-on-success-base: var(--vscode-charts-green); --text-on-success-weak: var(--vscode-charts-green); --text-on-success-strong: var(--vscode-charts-green); - --text-on-critical-base: var(--vscode-charts-red); - --text-on-critical-weak: var(--vscode-charts-red); - --text-on-critical-strong: var(--vscode-charts-red); + --text-on-critical-base: var(--vscode-errorForeground, var(--vscode-charts-red)); + --text-on-critical-weak: var(--vscode-errorForeground, var(--vscode-charts-red)); + --text-on-critical-strong: var(--vscode-errorForeground, var(--vscode-charts-red)); --text-on-warning-base: var(--vscode-charts-yellow); --text-on-warning-weak: var(--vscode-charts-yellow); --text-on-warning-strong: var(--vscode-charts-yellow); @@ -183,9 +192,9 @@ html[data-theme="kilo-vscode"] { --border-warning-base: var(--vscode-charts-yellow); --border-warning-hover: var(--vscode-charts-yellow); --border-warning-selected: var(--vscode-charts-yellow); - --border-critical-base: var(--vscode-charts-red); - --border-critical-hover: var(--vscode-charts-red); - --border-critical-selected: var(--vscode-charts-red); + --border-critical-base: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground, var(--vscode-charts-red))); + --border-critical-hover: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground, var(--vscode-charts-red))); + --border-critical-selected: var(--vscode-inputValidation-errorBorder, var(--vscode-errorForeground, var(--vscode-charts-red))); --border-info-base: var(--vscode-charts-blue); --border-info-hover: var(--vscode-charts-blue); --border-info-selected: var(--vscode-charts-blue); @@ -221,9 +230,9 @@ html[data-theme="kilo-vscode"] { --icon-warning-base: var(--vscode-charts-yellow); --icon-warning-hover: var(--vscode-charts-yellow); --icon-warning-active: var(--vscode-charts-yellow); - --icon-critical-base: var(--vscode-charts-red); - --icon-critical-hover: var(--vscode-charts-red); - --icon-critical-active: var(--vscode-charts-red); + --icon-critical-base: var(--vscode-errorForeground, var(--vscode-charts-red)); + --icon-critical-hover: var(--vscode-errorForeground, var(--vscode-charts-red)); + --icon-critical-active: var(--vscode-errorForeground, var(--vscode-charts-red)); --icon-info-base: var(--vscode-charts-blue); --icon-info-hover: var(--vscode-charts-blue); --icon-info-active: var(--vscode-charts-blue); @@ -239,9 +248,9 @@ html[data-theme="kilo-vscode"] { --icon-on-warning-base: var(--vscode-charts-yellow); --icon-on-warning-hover: var(--vscode-charts-yellow); --icon-on-warning-selected: var(--vscode-charts-yellow); - --icon-on-critical-base: var(--vscode-charts-red); - --icon-on-critical-hover: var(--vscode-charts-red); - --icon-on-critical-selected: var(--vscode-charts-red); + --icon-on-critical-base: var(--vscode-errorForeground, var(--vscode-charts-red)); + --icon-on-critical-hover: var(--vscode-errorForeground, var(--vscode-charts-red)); + --icon-on-critical-selected: var(--vscode-errorForeground, var(--vscode-charts-red)); --icon-on-info-base: var(--vscode-charts-blue); --icon-on-info-hover: var(--vscode-charts-blue); --icon-on-info-selected: var(--vscode-charts-blue); @@ -273,28 +282,22 @@ html[data-theme="kilo-vscode"] { --syntax-object: var(--vscode-editor-foreground); --syntax-success: var(--vscode-charts-green); --syntax-warning: var(--vscode-charts-yellow); - --syntax-critical: var(--vscode-charts-red); + --syntax-critical: var(--vscode-errorForeground, var(--vscode-charts-red)); --syntax-info: var(--vscode-charts-blue); --syntax-diff-add: var(--vscode-gitDecoration-addedResourceForeground); --syntax-diff-delete: var(--vscode-gitDecoration-deletedResourceForeground); --syntax-diff-unknown: var(--vscode-charts-red); /* ===== Pierre diff engine (theme its CSS vars to VS Code editor colors) ===== */ - --diffs-light-bg: var(--background-stronger); - --diffs-dark-bg: var(--background-stronger); - - /* Pierre 1.1 mixes line and gutter tints from the diff color. - Only word emphasis uses a final background override. */ - --diffs-bg-addition-emphasis-override: color-mix( - in lab, - var(--background-stronger) 60%, - var(--syntax-diff-add, #318430) - ); - --diffs-bg-deletion-emphasis-override: color-mix( - in lab, - var(--background-stronger) 60%, - var(--syntax-diff-delete, #da3319) + --diffs-light-bg: var(--vscode-editor-background, #1e1e1e); + --diffs-dark-bg: var(--vscode-editor-background, #1e1e1e); + --diffs-bg-separator-override: var(--surface-diff-skip-base); + --diffs-fg-number-override: var( + --vscode-diffEditor-unchangedRegionForeground, + var(--vscode-editorLineNumber-foreground, var(--vscode-descriptionForeground)) ); + --diffs-bg-addition-emphasis-override: var(--surface-diff-add-weak); + --diffs-bg-deletion-emphasis-override: var(--surface-diff-delete-weak); /* ===== Markdown ===== */ --markdown-heading: var(--vscode-textLink-foreground); diff --git a/packages/kilo-vscode/CHANGELOG.md b/packages/kilo-vscode/CHANGELOG.md index 5ff97fa7d68..c651b09a990 100644 --- a/packages/kilo-vscode/CHANGELOG.md +++ b/packages/kilo-vscode/CHANGELOG.md @@ -1,5 +1,40 @@ # kilo-code +## 7.3.14 + +### Minor Changes + +- [#10650](https://github.com/Kilo-Org/kilocode/pull/10650) [`f18a452`](https://github.com/Kilo-Org/kilocode/commit/f18a452082c998aa9f699204cda1fbf49fb3486f) - Add a "Not set (use server default)" option to the autocomplete model picker so users can follow the recommended default automatically. Users who previously had the default model pinned only because it was the only thing visible in the dropdown are migrated to "Not set" once. + +- [#10621](https://github.com/Kilo-Org/kilocode/pull/10621) [`29c3798`](https://github.com/Kilo-Org/kilocode/commit/29c3798faae2b82cba8ce531304630fee10f23b3) - Add Mercury Next Edit as an opt-in autocomplete mode. Predicts multi-line edits beyond the cursor (including off-cursor and pure-insertion edits) and surfaces them with a Tab-to-jump / Tab-to-apply affordance. Select "Mercury Next Edit" under the autocomplete model setting to enable it (requires an Inception API key). Thanks [@tfiras](https://github.com/tfiras)! + +- [#10644](https://github.com/Kilo-Org/kilocode/pull/10644) [`db38888`](https://github.com/Kilo-Org/kilocode/commit/db388889e867021c6bae42cbd03df6b67941b208) - Support Mercury Next Edit through the Kilo Gateway. The new "Mercury Next Edit via Kilo Gateway" autocomplete model routes Next Edit predictions through your Kilo account (no separate Inception API key required). + +- [#10608](https://github.com/Kilo-Org/kilocode/pull/10608) [`3ffacc8`](https://github.com/Kilo-Org/kilocode/commit/3ffacc847b79c8cdd44c17c4d26476998f24c098) - Make the Agent Manager tool available by default in VS Code. + +- [#10641](https://github.com/Kilo-Org/kilocode/pull/10641) [`4869d87`](https://github.com/Kilo-Org/kilocode/commit/4869d8722b423815a29832c812cf8a766c965a94) - Allow renaming sessions with a consistent inline editor in the active chat header and History, using safe bounded titles. + +### Patch Changes + +- [#10643](https://github.com/Kilo-Org/kilocode/pull/10643) [`6d77d6b`](https://github.com/Kilo-Org/kilocode/commit/6d77d6bbf293ebca7f76d848264d48073d29a44f) - Center local session history delete buttons within their rows. + +- [#10646](https://github.com/Kilo-Org/kilocode/pull/10646) [`d5a8989`](https://github.com/Kilo-Org/kilocode/commit/d5a8989b81d2cb0dd3ea4f62f3ee4570a7725891) - Improve the size and readability of the local History session context menu. + +- [#10619](https://github.com/Kilo-Org/kilocode/pull/10619) [`117691e`](https://github.com/Kilo-Org/kilocode/commit/117691e4d6fe48f91223bb7d7e24103c67cde73f) - Use supported hosted model presets for Kilo indexing and clear obsolete model and dimension overrides. + +- [#10642](https://github.com/Kilo-Org/kilocode/pull/10642) [`5a8d6ae`](https://github.com/Kilo-Org/kilocode/commit/5a8d6ae5dc8ed5d22117da96e7ee713b1a6e567b) - Restore readable diff highlighting and collapsed unchanged sections in VS Code themes. + +- [#10656](https://github.com/Kilo-Org/kilocode/pull/10656) [`d25d5ff`](https://github.com/Kilo-Org/kilocode/commit/d25d5ff473cbac8e230042d746b440465a259f11) - Keep the VS Code chat position stable when reading earlier output during a streaming response. + +- [#10652](https://github.com/Kilo-Org/kilocode/pull/10652) [`3af4c7e`](https://github.com/Kilo-Org/kilocode/commit/3af4c7ebabc2b95ece1c60cabb07930f9d4f42e6) - Warn when a chat turn stops unexpectedly or ends while tracked to-dos remain unfinished. + +- Updated dependencies [[`117691e`](https://github.com/Kilo-Org/kilocode/commit/117691e4d6fe48f91223bb7d7e24103c67cde73f), [`db38888`](https://github.com/Kilo-Org/kilocode/commit/db388889e867021c6bae42cbd03df6b67941b208)]: + - @kilocode/kilo-indexing@7.3.13 + - @kilocode/sdk@7.3.13 + - @kilocode/kilo-gateway@7.4.0 + - @kilocode/kilo-ui@7.3.13 + - @opencode-ai/ui@7.3.13 + ## 7.3.11 ### Minor Changes diff --git a/packages/kilo-vscode/README.md b/packages/kilo-vscode/README.md index 328d3f5d623..691da60553f 100644 --- a/packages/kilo-vscode/README.md +++ b/packages/kilo-vscode/README.md @@ -23,6 +23,8 @@ - [VS Code Marketplace](https://kilo.ai/vscode-marketplace?utm_source=Readme) (download) - [Official Kilo.ai Home page](https://kilo.ai) (learn more) +> 🚀 **Coming from Roo Code?** Switch to Kilo and check out our [migration guide](https://kilo.ai/articles/roo-to-kilo-migration-guide)! + ## Key Features - **Code Generation:** Kilo can generate code using natural language. diff --git a/packages/kilo-vscode/eslint.config.mjs b/packages/kilo-vscode/eslint.config.mjs index 0914b0366f7..b36ae0fd196 100644 --- a/packages/kilo-vscode/eslint.config.mjs +++ b/packages/kilo-vscode/eslint.config.mjs @@ -34,11 +34,12 @@ export default [ }, // ── Complexity exceptions ───────────────────────────────────────── - // Existing violations capped at their current max. - // New code must stay ≤ 20. Do not raise these caps; refactor instead. + // Existing complexity violations are capped at their current max. + // New code must stay ≤ 20. Do not raise complexity caps; refactor instead. { files: ["src/KiloProvider.ts"], - rules: { complexity: ["error", 150], "max-lines": ["error", 3600] }, + // This is the extension integration surface; do not gate feature work on line-count churn. + rules: { complexity: ["error", 150], "max-lines": "off" }, }, { files: ["webview-ui/agent-manager/AgentManagerApp.tsx"], diff --git a/packages/kilo-vscode/package.json b/packages/kilo-vscode/package.json index 3627dd898a3..2ddf7c0d5ca 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.3.12", + "version": "7.3.14", "icon": "assets/icons/logo-outline-black.png", "galleryBanner": { "color": "#FFFFFF", @@ -845,18 +845,20 @@ "enum": [ "mistralai/codestral-2508", "inception/mercury-edit-2", + "inception/mercury-next-edit", "codestral-2508", "mercury-edit-2", "mercury-next-edit" ], "enumDescriptions": [ - "Codestral via Kilo Gateway (default)", + "Codestral via Kilo Gateway", "Mercury Edit 2 via Kilo Gateway", + "Mercury Next Edit (multi-line edit predictions with jump-to-edit UX) via Kilo Gateway", "Codestral via your connected Mistral provider API key", "Mercury Edit 2 (FIM) via your connected Inception provider API key", "Mercury Next Edit (multi-line edit predictions with jump-to-edit UX) via your connected Inception provider API key" ], - "description": "Model to use for inline autocomplete suggestions" + "description": "Model to use for inline autocomplete suggestions. If unset, the recommended default is used." }, "kilo-code.new.autocomplete.provider": { "type": "string", diff --git a/packages/kilo-vscode/src/KiloProvider.ts b/packages/kilo-vscode/src/KiloProvider.ts index 8af621b930c..8657c062cf2 100644 --- a/packages/kilo-vscode/src/KiloProvider.ts +++ b/packages/kilo-vscode/src/KiloProvider.ts @@ -48,7 +48,12 @@ import { GitOps } from "./agent-manager/GitOps" import { GitStatsPoller, type LocalStats } from "./agent-manager/GitStatsPoller" import { diffSummary as localDiffSummary } from "./agent-manager/local-diff" import { getWorkspaceRoot } from "./review-utils" -import { MarketplaceService, type MarketplaceItem, type RemoveResult } from "./services/marketplace" +import { + MarketplaceService, + type MarketplaceItem, + type AgentMarketplaceItem, + type RemoveResult, +} from "./services/marketplace" import type { RemoteStatusService } from "./services/RemoteStatusService" import { resolveProjectDirectory } from "./project-directory" import { getBusySessionCount, seedSessionStatuses } from "./session-status" @@ -57,6 +62,7 @@ import { retry } from "./services/cli-backend/retry" import { slimPart, slimParts } from "./kilo-provider/slim-metadata" import { handleSidebarWorktreeMessage } from "./kilo-provider/sidebar-worktree" import { parseMessageFiles, type MessageFile } from "./kilo-provider/message-files" +import { renameSession } from "./kilo-provider/rename-session" import { handleFileSearch } from "./kilo-provider/file-search" import { watchFontSizeConfig } from "./kilo-provider/font-size" import { getTerminalContents } from "./services/terminal/context" @@ -831,8 +837,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper console.error("[Kilo New] removeSkill failed:", e), ) break - case "removeMode": - this.handleRemoveMode(message.name).catch((e) => console.error("[Kilo New] handleRemoveMode failed:", e)) + case "removeAgent": + this.handleRemoveAgent(message.name).catch((e) => console.error("[Kilo New] handleRemoveAgent failed:", e)) break case "removeMcp": this.handleRemoveMcp(message.name).catch((e) => console.error("[Kilo New] handleRemoveMcp failed:", e)) @@ -1128,6 +1134,10 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper }) break } + case "dismissAgentMigrationBanner": { + await this.extensionContext?.globalState.update("kilo.agentMigrationBannerDismissed", true) + break + } } }) this.webviewMessageDisposable = watchFontSizeConfig((msg) => this.postMessage(msg), this.webviewMessageDisposable) @@ -1150,7 +1160,8 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper const mp = this.getMarketplace() const skills = await this.fetchCliSkills() const data = await mp.fetchData(workspace, skills) - this.postMessage({ type: "marketplaceData", ...data }) + const dismissed = this.extensionContext?.globalState.get("kilo.agentMigrationBannerDismissed") ?? false + this.postMessage({ type: "marketplaceData", ...data, showAgentMigrationBanner: !dismissed }) } /** @@ -1659,27 +1670,18 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper * Handle renaming a session. */ private async handleRenameSession(sessionID: string, title: string): Promise { - if (!this.client) { - this.postMessage({ type: "error", message: "Not connected to CLI backend" }) - return - } - try { - const workspaceDir = this.getWorkspaceDirectory(sessionID) - const { data: updated } = await this.client.session.update( - { sessionID, directory: workspaceDir, title }, - { throwOnError: true }, - ) - if (this.currentSession?.id === sessionID) { - this.setCurrentSession(updated) - } + const updated = await renameSession({ + client: this.client, + sessionID, + title, + directory: this.getWorkspaceDirectory(sessionID), + }) + if (this.currentSession?.id === sessionID) this.setCurrentSession(updated) this.postMessage({ type: "sessionUpdated", session: this.sessionToWebview(updated) }) } catch (error) { console.error("[Kilo New] KiloProvider: Failed to rename session:", error) - this.postMessage({ - type: "error", - message: getErrorMessage(error) || "Failed to rename session", - }) + this.postMessage({ type: "error", message: getErrorMessage(error) || "Failed to rename session" }) } } @@ -1953,32 +1955,28 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper return true } - /** - * Remove a custom mode via the CLI backend (deletes from disk + refreshes state). - * The webview optimistically removes the mode from its list before this runs. - * On failure, re-fetches agents so the webview reverts to the authoritative state. - */ - private async handleRemoveMode(name: string): Promise { + /** Remove an agent via CLI, falling back to kilo.json removal. */ + private async handleRemoveAgent(name: string): Promise { if (!this.client) return - - // 1. Try CLI removal (handles .md files and legacy .kilocodemodes) try { - const dir = this.getWorkspaceDirectory() - const result = await this.client.kilocode.removeAgent({ name, directory: dir }) + const result = await this.client.kilocode.removeAgent({ name, directory: this.getWorkspaceDirectory() }) if (!result.error) { this.cachedAgentsMessage = null await this.fetchAndSendAgents() return } } catch { - // CLI removal failed — agent may be in kilo.json instead + // fall through to kilo.json removal } - - // 2. Try removing from kilo.json (handles marketplace-installed modes) - const stub = { id: name, type: "mode" as const, name, description: "", content: "" } - const removed = await this.removeMarketplaceItemFromAllScopes(stub) - if (!removed) { - console.error("[Kilo New] KiloProvider: Failed to remove mode:", name) + const stub: AgentMarketplaceItem = { + id: name, + type: "agent", + name, + description: "", + content: { mode: "primary", description: "", prompt: "" }, + } + if (!(await this.removeMarketplaceItemFromAllScopes(stub))) { + console.error("[Kilo New] KiloProvider: Failed to remove agent:", name) } } @@ -3038,7 +3036,11 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper const { section, leaf } = buildSettingPath(key) if (section === "autocomplete" && !validAutocompleteSetting(leaf, value)) return const config = vscode.workspace.getConfiguration(`kilo-code.new${section ? `.${section}` : ""}`) - await config.update(leaf, value, vscode.ConfigurationTarget.Global) + // Normalize a webview-side clear to `undefined` so VS Code removes the + // key from settings.json rather than persisting a literal `null`. This + // lets the runtime fall back to the resolved default. + const next = value === null ? undefined : value + await config.update(leaf, next, vscode.ConfigurationTarget.Global) } /** @@ -3074,6 +3076,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper await this.extensionContext?.globalState.update("variantSelections", undefined) await this.extensionContext?.globalState.update("recentModels", undefined) await this.extensionContext?.globalState.update("kilo.dismissedNotificationIds", undefined) + await this.extensionContext?.globalState.update("kilo.agentMigrationBannerDismissed", undefined) // Re-send all settings to the webview so the UI reflects the reset this.postMessage(buildAutocompleteSettingsMessage()) diff --git a/packages/kilo-vscode/src/extension.ts b/packages/kilo-vscode/src/extension.ts index 60e972d82e4..e45d49bbe33 100644 --- a/packages/kilo-vscode/src/extension.ts +++ b/packages/kilo-vscode/src/extension.ts @@ -487,7 +487,7 @@ export function activate(context: vscode.ExtensionContext) { ) // Register autocomplete provider - registerAutocompleteProvider(context, connectionService) + void registerAutocompleteProvider(context, connectionService) // Register commit message generation registerCommitMessageService(context, connectionService) diff --git a/packages/kilo-vscode/src/kilo-provider-utils.ts b/packages/kilo-vscode/src/kilo-provider-utils.ts index 6f0409f90e1..c8ceef403ba 100644 --- a/packages/kilo-vscode/src/kilo-provider-utils.ts +++ b/packages/kilo-vscode/src/kilo-provider-utils.ts @@ -388,6 +388,7 @@ export type WebviewMessage = message: Record } | { type: "sessionStatus"; sessionID: string; status: string; attempt?: number; message?: string; next?: number } + | { type: "sessionTurnClosed"; sessionID: string; reason: "completed" | "error" | "interrupted" } | { type: "permissionRequest" permission: { @@ -509,6 +510,12 @@ export function mapSSEEventToWebviewMessage(event: Event, sessionID: string | un ...extra, } } + case "session.turn.close": + return { + type: "sessionTurnClosed", + sessionID: event.properties.sessionID, + reason: event.properties.reason, + } case "permission.asked": return { type: "permissionRequest", diff --git a/packages/kilo-vscode/src/kilo-provider/rename-session.ts b/packages/kilo-vscode/src/kilo-provider/rename-session.ts new file mode 100644 index 00000000000..62b06a04637 --- /dev/null +++ b/packages/kilo-vscode/src/kilo-provider/rename-session.ts @@ -0,0 +1,18 @@ +import type { KiloClient, Session } from "@kilocode/sdk/v2/client" +import { parseSessionTitle } from "../shared/session-title" + +export async function renameSession(input: { + client: KiloClient | null + sessionID: string + title: unknown + directory: string +}): Promise { + if (!input.client) throw new Error("Not connected to CLI backend") + const result = parseSessionTitle(input.title) + if ("error" in result) throw new Error("Invalid session title") + const { data } = await input.client.session.update( + { sessionID: input.sessionID, directory: input.directory, title: result.value }, + { throwOnError: true }, + ) + return data +} diff --git a/packages/kilo-vscode/src/services/autocomplete/AutocompleteServiceManager.ts b/packages/kilo-vscode/src/services/autocomplete/AutocompleteServiceManager.ts index 2e00bb4389a..5c24286e782 100644 --- a/packages/kilo-vscode/src/services/autocomplete/AutocompleteServiceManager.ts +++ b/packages/kilo-vscode/src/services/autocomplete/AutocompleteServiceManager.ts @@ -109,6 +109,10 @@ export class AutocompleteServiceManager { this.nextEditProvider = new NextEditInlineCompletionProvider({ connectionService, suggestionManager: this.nextEditSuggestionManager, + getModelSelection: () => { + const info = getAutocompleteModel(this.settings?.provider, this.settings?.model) + return { providerId: info.providerID, modelId: info.modelID } + }, isFileAllowed: async (fsPath) => { const ignore = await this.inlineCompletionProvider.ignoreController return ignore.validateAccess(fsPath) diff --git a/packages/kilo-vscode/src/services/autocomplete/__tests__/settings.spec.ts b/packages/kilo-vscode/src/services/autocomplete/__tests__/settings.spec.ts index 04574cad6e3..43bf1438ae4 100644 --- a/packages/kilo-vscode/src/services/autocomplete/__tests__/settings.spec.ts +++ b/packages/kilo-vscode/src/services/autocomplete/__tests__/settings.spec.ts @@ -33,45 +33,31 @@ describe("autocomplete settings", () => { expect(buildAutocompleteSettingsMessage().settings.model).toBe("mercury-edit-2") }) - it("does not infer direct provider from a bare model name when provider is unset", async () => { - // Safety: a legacy `model` setting alone must never silently route to a - // direct BYOK provider. Direct providers require an explicit `provider`. + it("passes a bare model setting through unchanged so the webview can render it as-is", async () => { + // The webview now distinguishes "no explicit setting" (null) from "user + // picked something." We don't try to interpret a bare `model` here — + // resolving it to a default happens at the runtime layer, not in the + // settings message. state.set("model", "mercury-edit-2") const { buildAutocompleteSettingsMessage } = await import("../settings") - expect(buildAutocompleteSettingsMessage().settings.provider).toBe("kilo") - expect(buildAutocompleteSettingsMessage().settings.model).toBe("mistralai/codestral-2508") + expect(buildAutocompleteSettingsMessage().settings.provider).toBeNull() + expect(buildAutocompleteSettingsMessage().settings.model).toBe("mercury-edit-2") }) - it("defaults to codestral when no model is set", async () => { + it("returns null for both keys when nothing is set (let the webview render 'Not set')", async () => { const { buildAutocompleteSettingsMessage } = await import("../settings") - expect(buildAutocompleteSettingsMessage().settings.provider).toBe("kilo") - expect(buildAutocompleteSettingsMessage().settings.model).toBe("mistralai/codestral-2508") + expect(buildAutocompleteSettingsMessage().settings.provider).toBeNull() + expect(buildAutocompleteSettingsMessage().settings.model).toBeNull() }) - it("defaults to codestral when stored model is no longer supported", async () => { + it("preserves an unsupported stored model verbatim — runtime fallback handles resolution", async () => { state.set("model", "some/removed-model") const { buildAutocompleteSettingsMessage } = await import("../settings") - expect(buildAutocompleteSettingsMessage().settings.provider).toBe("kilo") - expect(buildAutocompleteSettingsMessage().settings.model).toBe("mistralai/codestral-2508") - }) - - it("maps legacy inception/mercury-edit to Kilo Gateway Mercury", async () => { - state.set("model", "inception/mercury-edit") - const { buildAutocompleteSettingsMessage } = await import("../settings") - - expect(buildAutocompleteSettingsMessage().settings.provider).toBe("kilo") - expect(buildAutocompleteSettingsMessage().settings.model).toBe("inception/mercury-edit-2") - }) - - it("maps legacy inception/mercury-edit-2 to Kilo Gateway Mercury", async () => { - state.set("model", "inception/mercury-edit-2") - const { buildAutocompleteSettingsMessage } = await import("../settings") - - expect(buildAutocompleteSettingsMessage().settings.provider).toBe("kilo") - expect(buildAutocompleteSettingsMessage().settings.model).toBe("inception/mercury-edit-2") + expect(buildAutocompleteSettingsMessage().settings.provider).toBeNull() + expect(buildAutocompleteSettingsMessage().settings.model).toBe("some/removed-model") }) it("validates supported model updates", async () => { @@ -81,12 +67,20 @@ describe("autocomplete settings", () => { expect(validAutocompleteSetting("provider", "inception")).toBe(true) }) + it("accepts null/undefined for provider and model so users can clear the setting", async () => { + const { validAutocompleteSetting } = await import("../settings") + + expect(validAutocompleteSetting("provider", null)).toBe(true) + expect(validAutocompleteSetting("provider", undefined)).toBe(true) + expect(validAutocompleteSetting("model", null)).toBe(true) + expect(validAutocompleteSetting("model", undefined)).toBe(true) + }) + it("rejects unsupported autocomplete updates", async () => { const { validAutocompleteSetting } = await import("../settings") expect(validAutocompleteSetting("model", "other/model")).toBe(false) - expect(validAutocompleteSetting("provider", undefined)).toBe(false) - expect(validAutocompleteSetting("provider", null)).toBe(false) + expect(validAutocompleteSetting("provider", "openrouter")).toBe(false) }) it("rejects non-boolean toggle updates", async () => { diff --git a/packages/kilo-vscode/src/services/autocomplete/index.ts b/packages/kilo-vscode/src/services/autocomplete/index.ts index a27f838616c..7b106dc03c1 100644 --- a/packages/kilo-vscode/src/services/autocomplete/index.ts +++ b/packages/kilo-vscode/src/services/autocomplete/index.ts @@ -1,15 +1,22 @@ import * as vscode from "vscode" import { AutocompleteServiceManager } from "./AutocompleteServiceManager" import { ensureBackendForAutocomplete } from "./ensure-backend" +import { migrateDefaultAutocompleteSettings } from "./migrate-default" import { nesLog } from "./next-edit/log" import { INLINE_COMPLETION_ACCEPTED_COMMAND as NEXT_EDIT_ACCEPTED_COMMAND } from "./next-edit/NextEditInlineCompletionProvider" import { chainNextPrediction } from "./next-edit/NextEditSuggestionManager" import type { KiloConnectionService } from "../cli-backend" -export const registerAutocompleteProvider = ( +export const registerAutocompleteProvider = async ( context: vscode.ExtensionContext, connectionService: KiloConnectionService, ) => { + // Run before constructing the manager so its initial readSettings() sees + // the cleared state and behaves as "Not set." Awaited because the manager's + // constructor synchronously kicks off readSettings() via load(), which would + // otherwise race with the migration. + await migrateDefaultAutocompleteSettings(context) + const autocompleteManager = new AutocompleteServiceManager(context, connectionService) context.subscriptions.push(autocompleteManager) diff --git a/packages/kilo-vscode/src/services/autocomplete/migrate-default.ts b/packages/kilo-vscode/src/services/autocomplete/migrate-default.ts new file mode 100644 index 00000000000..9a4eeed4145 --- /dev/null +++ b/packages/kilo-vscode/src/services/autocomplete/migrate-default.ts @@ -0,0 +1,40 @@ +import * as vscode from "vscode" +import { DEFAULT_AUTOCOMPLETE_MODEL } from "../../shared/autocomplete-models" + +const FLAG = "kilo.autocomplete.defaultClearMigrationV1" + +/** + * One-time migration: clear `kilo-code.new.autocomplete.{provider,model}` when + * they exactly match the current `DEFAULT_AUTOCOMPLETE_MODEL`. Many users have + * the default explicitly stored only because it was the only thing visible in + * the dropdown — leaving it pinned would block them from picking up future + * default changes (e.g. a switch to Mercury Next Edit) silently. After the + * migration runs they show up as "Not set" and follow the resolved default. + * + * Users who picked a different model are untouched. The migration runs once + * per machine and is gated on a globalState flag. + * + * TODO(2026-09): remove this migration. By September 2026 the cohort that + * needed it will either have migrated already or be fine staying pinned. + */ +export async function migrateDefaultAutocompleteSettings(context: vscode.ExtensionContext): Promise { + if (context.globalState.get(FLAG)) return + + const config = vscode.workspace.getConfiguration("kilo-code.new.autocomplete") + // Read the user/global scope specifically. `get()` returns the merged + // effective value (workspace > global > default), which would let a + // workspace-level pin or the schema default falsely look like a stored + // global default and cause us to no-op while still flipping the flag. + const provider = config.inspect("provider")?.globalValue + const model = config.inspect("model")?.globalValue + + const matchesDefault = + provider === DEFAULT_AUTOCOMPLETE_MODEL.providerID && model === DEFAULT_AUTOCOMPLETE_MODEL.modelID + + if (matchesDefault) { + await config.update("provider", undefined, vscode.ConfigurationTarget.Global) + await config.update("model", undefined, vscode.ConfigurationTarget.Global) + } + + await context.globalState.update(FLAG, true) +} diff --git a/packages/kilo-vscode/src/services/autocomplete/next-edit/MercuryEditProvider.ts b/packages/kilo-vscode/src/services/autocomplete/next-edit/MercuryEditProvider.ts index 4079a35a40a..e1886b8639b 100644 --- a/packages/kilo-vscode/src/services/autocomplete/next-edit/MercuryEditProvider.ts +++ b/packages/kilo-vscode/src/services/autocomplete/next-edit/MercuryEditProvider.ts @@ -3,13 +3,17 @@ import { nesLog, nesWarn } from "./log" import type { MercuryEditRequestContext, MercuryEditSuggestion } from "./types" const MERCURY_MAX_TOKENS = 512 -const PROVIDER_ID = "inception" -const MODEL_ID = "mercury-next-edit" +const DEFAULT_PROVIDER_ID = "inception" +const DEFAULT_MODEL_ID = "mercury-next-edit" type EditResponseData = { content?: string; usage?: { prompt_tokens?: number; completion_tokens?: number } } export interface MercuryEditProviderOptions { connectionService: KiloConnectionService + /** Provider id to send to the gateway (e.g. `"kilo"` or `"inception"`). */ + providerId?: string + /** Model id to send to the gateway (e.g. `"inception/mercury-next-edit"`). */ + modelId?: string /** AbortSignal for cancellation (cursor moves, escape, etc.). */ signal?: AbortSignal } @@ -25,8 +29,10 @@ export class MercuryEditProvider { async suggest(ctx: MercuryEditRequestContext): Promise { const start = Date.now() + const provider = this.options.providerId ?? DEFAULT_PROVIDER_ID + const model = this.options.modelId ?? DEFAULT_MODEL_ID nesLog( - `-> /kilo/edit model=${MODEL_ID} region=[${ctx.editableRegionStartLine},${ctx.editableRegionEndLine}] diffs=${ctx.editDiffHistory.length} snippets=${ctx.recentlyViewedSnippets.length}`, + `-> /kilo/edit provider=${provider} model=${model} region=[${ctx.editableRegionStartLine},${ctx.editableRegionEndLine}] diffs=${ctx.editDiffHistory.length} snippets=${ctx.recentlyViewedSnippets.length}`, ) const client = await this.options.connectionService.getClientAsync() @@ -34,8 +40,8 @@ export class MercuryEditProvider { // Send structured editor context; the gateway assembles the Mercury prompt. const { data, error, response } = await client.kilo.edit( { - provider: PROVIDER_ID, - model: MODEL_ID, + provider, + model, maxTokens: MERCURY_MAX_TOKENS, currentFilePath: ctx.currentFilePath, currentFileContent: ctx.currentFileContent, diff --git a/packages/kilo-vscode/src/services/autocomplete/next-edit/NextEditInlineCompletionProvider.ts b/packages/kilo-vscode/src/services/autocomplete/next-edit/NextEditInlineCompletionProvider.ts index 3a99f66b14a..5d613465c5b 100644 --- a/packages/kilo-vscode/src/services/autocomplete/next-edit/NextEditInlineCompletionProvider.ts +++ b/packages/kilo-vscode/src/services/autocomplete/next-edit/NextEditInlineCompletionProvider.ts @@ -22,6 +22,8 @@ export interface NextEditProviderDeps { onFatalError?: (status: number | null) => void /** Stash for diffs that don't land on the cursor's line — rendered as a jump affordance. */ suggestionManager?: NextEditSuggestionManager + /** Resolves the currently selected (provider, model) at request time. */ + getModelSelection?: () => { providerId: string; modelId: string } } export interface NextEditSuggestionEvent { @@ -78,8 +80,11 @@ export class NextEditInlineCompletionProvider implements vscode.InlineCompletion const abort = this.swapAbortController(token) const ctx = await this.buildRequestContext(document, position) + const sel = this.deps.getModelSelection?.() const provider = new MercuryEditProvider({ connectionService: this.deps.connectionService, + providerId: sel?.providerId, + modelId: sel?.modelId, signal: abort.signal, }) diff --git a/packages/kilo-vscode/src/services/autocomplete/settings.ts b/packages/kilo-vscode/src/services/autocomplete/settings.ts index 1312de8f9b1..0a3f189d58b 100644 --- a/packages/kilo-vscode/src/services/autocomplete/settings.ts +++ b/packages/kilo-vscode/src/services/autocomplete/settings.ts @@ -1,9 +1,5 @@ import * as vscode from "vscode" -import { - getAutocompleteModel, - validAutocompleteModel, - validAutocompleteProvider, -} from "../../shared/autocomplete-models" +import { validAutocompleteModel, validAutocompleteProvider } from "../../shared/autocomplete-models" type Message = { type: string @@ -22,15 +18,17 @@ export async function routeAutocompleteMessage(message: Message, post: Post): Pr export function buildAutocompleteSettingsMessage() { const config = vscode.workspace.getConfiguration("kilo-code.new.autocomplete") - const info = getAutocompleteModel(config.get("provider"), config.get("model")) + // Pass through provider/model as-is (null when unset) so the webview can + // distinguish "user hasn't picked" from "user picked the current default." + // The runtime resolves null → DEFAULT_AUTOCOMPLETE_MODEL via getAutocompleteModel(). return { type: "autocompleteSettingsLoaded" as const, settings: { enableAutoTrigger: config.get("enableAutoTrigger", true), enableSmartInlineTaskKeybinding: config.get("enableSmartInlineTaskKeybinding", false), enableChatAutocomplete: config.get("enableChatAutocomplete", false), - provider: info.providerID, - model: info.modelID, + provider: config.get("provider") ?? null, + model: config.get("model") ?? null, }, } } @@ -46,10 +44,13 @@ export function watchAutocompleteConfig(post: Post): vscode.Disposable { export function validAutocompleteSetting(key: string, value: unknown) { if (key === "model") { + // Allow clearing back to the server-side default. + if (value === null || value === undefined) return true return validAutocompleteModel(value) } if (key === "provider") { + if (value === null || value === undefined) return true return validAutocompleteProvider(value) } diff --git a/packages/kilo-vscode/src/services/cli-backend/connection-utils.ts b/packages/kilo-vscode/src/services/cli-backend/connection-utils.ts index 787311ed03b..1b0a1dcfa62 100644 --- a/packages/kilo-vscode/src/services/cli-backend/connection-utils.ts +++ b/packages/kilo-vscode/src/services/cli-backend/connection-utils.ts @@ -16,6 +16,7 @@ export function resolveEventSessionId( case "session.updated": return event.properties.info.id case "session.status": + case "session.turn.close": case "session.idle": case "session.error": case "todo.updated": diff --git a/packages/kilo-vscode/src/services/marketplace/api.ts b/packages/kilo-vscode/src/services/marketplace/api.ts index c687d9f5997..5c1bd7c3c4b 100644 --- a/packages/kilo-vscode/src/services/marketplace/api.ts +++ b/packages/kilo-vscode/src/services/marketplace/api.ts @@ -1,5 +1,5 @@ import { parse as parseYaml } from "yaml" -import type { MarketplaceItem, McpMarketplaceItem, ModeMarketplaceItem, SkillMarketplaceItem, RawSkill } from "./types" +import type { MarketplaceItem, McpMarketplaceItem, AgentMarketplaceItem, SkillMarketplaceItem, RawSkill } from "./types" const BASE_URL = "https://api.kilo.ai/api/marketplace" const CACHE_TTL = 300_000 @@ -76,18 +76,6 @@ export class MarketplaceApiClient { this.cache.set(key, { data, timestamp: Date.now() }) } - private async fetchModes(): Promise { - const cached = this.getCached("modes") - if (cached) return cached as ModeMarketplaceItem[] - - const text = await fetchWithRetry(`${BASE_URL}/modes`) - const parsed = parseResponse(text) as { items?: unknown[] } - const items = (parsed.items ?? []) as Array> - const result = items.map((item) => ({ ...item, type: "mode" as const }) as ModeMarketplaceItem) - this.setCache("modes", result) - return result - } - private async fetchMcps(): Promise { const cached = this.getCached("mcps") if (cached) return cached as McpMarketplaceItem[] @@ -100,6 +88,18 @@ export class MarketplaceApiClient { return result } + private async fetchAgents(): Promise { + const cached = this.getCached("agents") + if (cached) return cached as AgentMarketplaceItem[] + + const text = await fetchWithRetry(`${BASE_URL}/agents`) + const parsed = parseResponse(text) as { items?: unknown[] } + const items = (parsed.items ?? []) as Array> + const result = items.map((item) => ({ ...item, type: "agent" as const }) as AgentMarketplaceItem) + this.setCache("agents", result) + return result + } + private async fetchSkills(): Promise { const cached = this.getCached("skills") if (cached) return cached as SkillMarketplaceItem[] @@ -116,9 +116,9 @@ export class MarketplaceApiClient { const errors: string[] = [] const settled = await Promise.all([ - this.fetchModes().catch((err: unknown) => { - errors.push(`Failed to fetch modes: ${err instanceof Error ? err.message : String(err)}`) - return [] as ModeMarketplaceItem[] + this.fetchAgents().catch((err: unknown) => { + errors.push(`Failed to fetch agents: ${err instanceof Error ? err.message : String(err)}`) + return [] as AgentMarketplaceItem[] }), this.fetchMcps().catch((err: unknown) => { errors.push(`Failed to fetch mcps: ${err instanceof Error ? err.message : String(err)}`) diff --git a/packages/kilo-vscode/src/services/marketplace/detection.ts b/packages/kilo-vscode/src/services/marketplace/detection.ts index 9f203d3ceb1..fb2030beb7d 100644 --- a/packages/kilo-vscode/src/services/marketplace/detection.ts +++ b/packages/kilo-vscode/src/services/marketplace/detection.ts @@ -16,6 +16,7 @@ export class InstallationDetector { /** * Detect installed marketplace items. * + * Agents are detected from .kilo/agents/*.md files. * MCP servers and modes are detected from kilo.json config files. * Skills come from the CLI backend (via GET /skill), which is the * authoritative source — it scans all skill directories. @@ -23,12 +24,14 @@ export class InstallationDetector { async detect(workspace?: string, skills?: CliSkill[]): Promise { const project = workspace ? Object.fromEntries([ + ...(await this.detectAgentFiles("project", workspace)), ...(await this.detectFromConfig(this.paths.configPath("project", workspace))), ...this.skillEntries(skills, workspace, true), ]) : {} const global = Object.fromEntries([ + ...(await this.detectAgentFiles("global")), ...(await this.detectFromConfig(this.paths.configPath("global"))), ...this.skillEntries(skills, workspace, false), ]) @@ -52,6 +55,20 @@ export class InstallationDetector { .map((s) => [s.name, { type: "skill" }]) } + /** Scan .kilo/agents/*.md files to detect installed marketplace agents. */ + private async detectAgentFiles(scope: "project" | "global", workspace?: string): Promise { + const dir = this.paths.agentsDir(scope, workspace) + try { + const files = await fs.readdir(dir) + return files.filter((f) => f.endsWith(".md")).map((f) => [path.basename(f, ".md"), { type: "agent" }] as Entry) + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== "ENOENT") { + console.warn(`Failed to detect agent files from ${dir}:`, err) + } + return [] + } + } + /** Read mcp and agent entries from a kilo.json config file. */ private async detectFromConfig(filepath: string): Promise { try { @@ -67,7 +84,7 @@ export class InstallationDetector { if (parsed?.agent && typeof parsed.agent === "object") { for (const key of Object.keys(parsed.agent)) { - entries.push([key, { type: "mode" }]) + entries.push([key, { type: "agent" }]) } } diff --git a/packages/kilo-vscode/src/services/marketplace/index.ts b/packages/kilo-vscode/src/services/marketplace/index.ts index cb2272e7168..148ec9e6d89 100644 --- a/packages/kilo-vscode/src/services/marketplace/index.ts +++ b/packages/kilo-vscode/src/services/marketplace/index.ts @@ -65,6 +65,7 @@ export class MarketplaceService { export type { MarketplaceItem, + AgentMarketplaceItem, InstallMarketplaceItemOptions, MarketplaceDataResponse, InstallResult, diff --git a/packages/kilo-vscode/src/services/marketplace/installer.ts b/packages/kilo-vscode/src/services/marketplace/installer.ts index eff254f1a06..6ec35af7620 100644 --- a/packages/kilo-vscode/src/services/marketplace/installer.ts +++ b/packages/kilo-vscode/src/services/marketplace/installer.ts @@ -7,7 +7,7 @@ import type { MarketplaceItem, SkillMarketplaceItem, McpMarketplaceItem, - ModeMarketplaceItem, + AgentMarketplaceItem, McpInstallationMethod, InstallMarketplaceItemOptions, InstallResult, @@ -26,7 +26,7 @@ export class MarketplaceInstaller { const scope = options.target ?? "project" if (item.type === "skill") return this.installSkill(item, scope, workspace) if (item.type === "mcp") return this.installMcp(item, options, scope, workspace) - return this.installMode(item, scope, workspace) + return this.installAgent(item, scope, workspace) } // ── MCP ───────────────────────────────────────────────────────────── @@ -81,10 +81,10 @@ export class MarketplaceInstaller { return normalizeMcpEntry(raw) } - // ── Mode ──────────────────────────────────────────────────────────── + // ── Agent ─────────────────────────────────────────────────────────── - async installMode( - item: ModeMarketplaceItem, + async installAgent( + item: AgentMarketplaceItem, scope: "project" | "global", workspace?: string, ): Promise { @@ -92,16 +92,72 @@ export class MarketplaceInstaller { return { success: false, slug: item.id, error: "No workspace directory for project-scope install" } } - const config = await this.readConfig(scope, workspace) - if (!config.agent) config.agent = {} - - if (config.agent[item.id]) { - return { success: false, slug: item.id, error: "Mode already installed. Remove it first." } + if (!isSafeId(item.id)) { + return { success: false, slug: item.id, error: "Invalid agent id" } } - config.agent[item.id] = convertModeToAgent(item.content) + const dir = this.paths.agentsDir(scope, workspace) + await fs.mkdir(dir, { recursive: true }) + + const filepath = path.join(dir, `${item.id}.md`) + if (!path.resolve(filepath).startsWith(path.resolve(dir))) { + return { success: false, slug: item.id, error: "Invalid agent id" } + } + + try { + await fs.access(filepath) + return { success: false, slug: item.id, error: "Agent already installed. Remove it first." } + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== "ENOENT") throw err + } + + const { prompt, ...front } = item.content + const frontmatter = yaml.stringify(front).trimEnd() + const content = `---\n${frontmatter}\n---\n\n${prompt}\n` + await fs.writeFile(filepath, content, "utf-8") + + // Migration: remove stale kilo.json agent entry with same id if present + const config = await this.readConfig(scope, workspace) + if (config.agent?.[item.id]) { + delete (config.agent as Record)[item.id] + if (Object.keys(config.agent as object).length === 0) delete config.agent + await this.writeConfig(scope, workspace, config) + } + + return { success: true, slug: item.id, filePath: filepath, line: 1 } + } + + async removeAgent( + item: AgentMarketplaceItem, + scope: "project" | "global", + workspace?: string, + ): Promise { + if (!isSafeId(item.id)) { + return { success: false, slug: item.id, error: "Invalid agent id" } + } + + const dir = this.paths.agentsDir(scope, workspace) + const filepath = path.join(dir, `${item.id}.md`) + if (!path.resolve(filepath).startsWith(path.resolve(dir))) { + return { success: false, slug: item.id, error: "Invalid agent id" } + } + + try { + await fs.unlink(filepath) + } catch (err) { + if ((err as NodeJS.ErrnoException).code !== "ENOENT") { + return { success: false, slug: item.id, error: String(err) } + } + } + + // Also clean up any stale kilo.json agent entry + const config = await this.readConfig(scope, workspace) + if (config.agent?.[item.id]) { + delete (config.agent as Record)[item.id] + if (Object.keys(config.agent as object).length === 0) delete config.agent + await this.writeConfig(scope, workspace, config) + } - await this.writeConfig(scope, workspace, config) return { success: true, slug: item.id } } @@ -191,7 +247,7 @@ export class MarketplaceInstaller { async remove(item: MarketplaceItem, scope: "project" | "global", workspace?: string): Promise { if (item.type === "skill") return this.removeSkill(item, scope, workspace) if (item.type === "mcp") return this.removeMcp(item, scope, workspace) - return this.removeMode(item, scope, workspace) + return this.removeAgent(item, scope, workspace) } async removeMcp(item: McpMarketplaceItem, scope: "project" | "global", workspace?: string): Promise { @@ -205,17 +261,6 @@ export class MarketplaceInstaller { return { success: true, slug: item.id } } - async removeMode(item: ModeMarketplaceItem, scope: "project" | "global", workspace?: string): Promise { - const config = await this.readConfig(scope, workspace) - if (!config.agent?.[item.id]) { - return { success: true, slug: item.id } - } - delete config.agent[item.id] - if (Object.keys(config.agent).length === 0) delete config.agent - await this.writeConfig(scope, workspace, config) - return { success: true, slug: item.id } - } - async removeSkill( item: SkillMarketplaceItem, scope: "project" | "global", @@ -318,47 +363,6 @@ function isSafeId(id: string): boolean { return /^[\w\-@.]+$/.test(id) } -// Group name → opencode permission key mapping (mirrors ModesMigrator) -const GROUP_PERMISSIONS: Record = { - read: "read", - edit: "edit", - browser: "bash", - command: "bash", - mcp: "mcp", -} -const ALL_PERMISSIONS = ["read", "edit", "bash", "mcp"] - -function convertModeToAgent(content: string): Record { - const mode = yaml.parse(content) as Record - const groups = (mode.groups ?? []) as Array]> - - const permission: Record = {} - const allowed = new Set() - for (const group of groups) { - if (typeof group === "string") { - const key = GROUP_PERMISSIONS[group] ?? group - allowed.add(key) - permission[key] = "allow" - } else if (Array.isArray(group)) { - const [name, cfg] = group - const key = GROUP_PERMISSIONS[name] ?? name - allowed.add(key) - permission[key] = cfg?.fileRegex ? { [String(cfg.fileRegex)]: "allow", "*": "deny" } : "allow" - } - } - for (const perm of ALL_PERMISSIONS) { - if (!allowed.has(perm)) permission[perm] = "deny" - } - - const prompt = [mode.roleDefinition, mode.customInstructions].filter(Boolean).join("\n\n") - return { - mode: "primary", - description: mode.description ?? mode.whenToUse ?? mode.name, - prompt, - permission, - } -} - function escapeJsonValue(raw: string): string { return raw .replace(/\\/g, "\\\\") diff --git a/packages/kilo-vscode/src/services/marketplace/paths.ts b/packages/kilo-vscode/src/services/marketplace/paths.ts index 112c6cad23d..d7c8c19582b 100644 --- a/packages/kilo-vscode/src/services/marketplace/paths.ts +++ b/packages/kilo-vscode/src/services/marketplace/paths.ts @@ -17,6 +17,12 @@ export class MarketplacePaths { return path.join(globalConfigDir(), "kilo.json") } + /** Agent install directory (where marketplace agents are written as .md files). */ + agentsDir(scope: "project" | "global", workspace?: string): string { + if (scope === "project") return path.join(workspace!, ".kilo", "agents") + return path.join(globalConfigDir(), "agents") + } + /** Skill install directory (where the marketplace installer writes to). */ skillsDir(scope: "project" | "global", workspace?: string): string { if (scope === "project") return path.join(workspace!, ".kilo", "skills") diff --git a/packages/kilo-vscode/src/services/marketplace/types.ts b/packages/kilo-vscode/src/services/marketplace/types.ts index c35ad472419..bfb20a6bd18 100644 --- a/packages/kilo-vscode/src/services/marketplace/types.ts +++ b/packages/kilo-vscode/src/services/marketplace/types.ts @@ -29,9 +29,17 @@ export interface McpMarketplaceItem extends MarketplaceItemBase { parameters?: McpParameter[] } -export interface ModeMarketplaceItem extends MarketplaceItemBase { - type: "mode" - content: string +export interface AgentContent { + mode: "primary" | "subagent" | "all" + description: string + prompt: string + options?: Record + permission?: Record +} + +export interface AgentMarketplaceItem extends MarketplaceItemBase { + type: "agent" + content: AgentContent } export interface RawSkill { @@ -51,7 +59,7 @@ export interface SkillMarketplaceItem extends MarketplaceItemBase { displayCategory: string } -export type MarketplaceItem = McpMarketplaceItem | ModeMarketplaceItem | SkillMarketplaceItem +export type MarketplaceItem = McpMarketplaceItem | AgentMarketplaceItem | SkillMarketplaceItem export interface InstallMarketplaceItemOptions { target?: "global" | "project" diff --git a/packages/kilo-vscode/src/shared/session-title.ts b/packages/kilo-vscode/src/shared/session-title.ts new file mode 100644 index 00000000000..a86e01360d7 --- /dev/null +++ b/packages/kilo-vscode/src/shared/session-title.ts @@ -0,0 +1,16 @@ +export const SESSION_TITLE_LIMIT = 200 + +// Block terminal/display controls and bidi marks that can visually spoof a title. +const unsafe = /[\u0000-\u001f\u007f-\u009f\u061c\u200e\u200f\u2028\u2029\u202a-\u202e\u2066-\u2069]/u + +type SessionTitleIssue = "invalid" | "required" | "too_long" | "control" +type SessionTitleResult = { value: string } | { error: SessionTitleIssue } + +export function parseSessionTitle(raw: unknown): SessionTitleResult { + if (typeof raw !== "string") return { error: "invalid" } + const value = raw.trim() + if (!value) return { error: "required" } + if (value.length > SESSION_TITLE_LIMIT) return { error: "too_long" } + if (unsafe.test(value)) return { error: "control" } + return { value } +} diff --git a/packages/kilo-vscode/tests/indexing-provider-blur-race.spec.ts b/packages/kilo-vscode/tests/indexing-provider-blur-race.spec.ts index 3b5b35beeae..c8f362f5705 100644 --- a/packages/kilo-vscode/tests/indexing-provider-blur-race.spec.ts +++ b/packages/kilo-vscode/tests/indexing-provider-blur-race.spec.ts @@ -10,15 +10,19 @@ if (IS_DARWIN) { const GLOBALS = "colorScheme:dark;theme:kilo-vscode;vscodeTheme:dark-modern" const STORY_ID = "settings--indexing-provider-blur-race" +const KILO_STORY_ID = "settings--indexing-kilo-model-preset" +const KILO_LOADING_STORY_ID = "settings--indexing-kilo-catalog-loading" type Saved = { provider?: string + model?: string | null + dimension?: number | null openai?: { apiKey?: string } gemini?: { apiKey?: string } } -function storyUrl() { - return `/iframe.html?id=${STORY_ID}&viewMode=story&globals=${GLOBALS}` +function storyUrl(id = STORY_ID) { + return `/iframe.html?id=${id}&viewMode=story&globals=${GLOBALS}` } async function disableAnimations(page: Page) { @@ -34,6 +38,10 @@ async function disableAnimations(page: Page) { }) } +function field(page: Page, title: string) { + return page.locator('[data-slot="settings-row"]', { hasText: title }).locator("input") +} + test("provider switch writes to selected provider bucket", async ({ page }) => { await page.setViewportSize({ width: 420, height: 720 }) await page.goto(storyUrl(), { waitUntil: "load" }) @@ -58,6 +66,55 @@ test("provider switch writes to selected provider bucket", async ({ page }) => { const cfg = JSON.parse(text) as Saved expect(cfg.provider).toBe("gemini") + expect(cfg.model).toBeNull() + expect(cfg.dimension).toBeNull() expect(cfg.openai?.apiKey ?? "").toBe("") expect(cfg.gemini?.apiKey ?? "").toBe("") + + const model = field(page, "Embedding model").first() + await expect(model).toHaveValue("") + await expect(model).toHaveAttribute("placeholder", "Enter model ID") +}) + +test("Kilo exposes only supported embedding model presets", async ({ page }) => { + await page.setViewportSize({ width: 420, height: 720 }) + await page.goto(storyUrl(KILO_STORY_ID), { waitUntil: "load" }) + await disableAnimations(page) + await page.waitForSelector("#storybook-root *", { state: "attached" }) + + await expect(page.getByText("Kilo model preset", { exact: true })).toBeVisible() + await expect(page.getByText("Embedding model", { exact: true })).toHaveCount(0) + await expect(page.getByText("Vector dimension", { exact: true })).toBeVisible() + + const preset = page.locator('[data-component="select"] [data-slot="select-select-trigger"]').nth(1) + await expect(preset).toContainText("Provider Model") + + const dimension = field(page, "Vector dimension").first() + await expect(dimension).toHaveValue("") + + await preset.click() + await page.locator('[data-slot="select-select-item-label"]', { hasText: "Provider Compact" }).click() + await expect(preset).toContainText("Provider Compact") +}) + +test("enabling Kilo before its catalog loads does not store an empty model", async ({ page }) => { + const saved = page.getByTestId("indexing-kilo-loading-save") + const cfg = async () => JSON.parse(((await saved.textContent()) ?? "{}").trim()) as Saved + const verify = async () => { + await expect.poll(async () => (await cfg()).provider).toBe("kilo") + expect((await cfg()).model).toBeNull() + expect((await cfg()).dimension).toBeNull() + } + + await page.setViewportSize({ width: 420, height: 720 }) + await page.goto(storyUrl(KILO_LOADING_STORY_ID), { waitUntil: "load" }) + await disableAnimations(page) + await page.waitForSelector("#storybook-root *", { state: "attached" }) + await page.locator('[data-component="switch"] [data-slot="switch-control"]').nth(1).click() + await verify() + + await page.goto(storyUrl(KILO_LOADING_STORY_ID), { waitUntil: "load" }) + await page.waitForSelector("#storybook-root *", { state: "attached" }) + await page.locator('[data-component="switch"] [data-slot="switch-control"]').first().click() + await verify() }) diff --git a/packages/kilo-vscode/tests/package.json b/packages/kilo-vscode/tests/package.json index 6974b0aa894..5eb8e64e604 100644 --- a/packages/kilo-vscode/tests/package.json +++ b/packages/kilo-vscode/tests/package.json @@ -1,6 +1,6 @@ { "type": "module", - "version": "7.3.12", + "version": "7.3.14", "dependencies": {}, "devDependencies": {}, "peerDependencies": {} diff --git a/packages/kilo-vscode/tests/unit/autocomplete-migrate-default.test.ts b/packages/kilo-vscode/tests/unit/autocomplete-migrate-default.test.ts new file mode 100644 index 00000000000..f031401dd24 --- /dev/null +++ b/packages/kilo-vscode/tests/unit/autocomplete-migrate-default.test.ts @@ -0,0 +1,157 @@ +import { describe, it, expect, afterEach, beforeEach } from "bun:test" +import * as vscode from "vscode" +import { migrateDefaultAutocompleteSettings } from "../../src/services/autocomplete/migrate-default" +import { DEFAULT_AUTOCOMPLETE_MODEL } from "../../src/shared/autocomplete-models" + +type Scoped = { globalValue?: unknown; workspaceValue?: unknown } +type State = Map + +type Stub = { + getConfiguration: (section?: string) => { + get: (key: string, fallback?: unknown) => unknown + inspect: (key: string) => Scoped | undefined + update: (key: string, value: unknown, target: unknown) => Promise + } +} + +const original = vscode.workspace.getConfiguration + +function makeContext(initial: Record = {}) { + const flag = new Map(Object.entries(initial)) + return { + flag, + context: { + globalState: { + get: (key: string) => flag.get(key) as T | undefined, + update: async (key: string, value: unknown) => { + flag.set(key, value) + }, + }, + } as any, + } +} + +function stubConfig(state: State) { + function entry(key: string): Scoped { + const e = state.get(key) + if (e) return e + const fresh: Scoped = {} + state.set(key, fresh) + return fresh + } + ;(vscode.workspace as unknown as Stub).getConfiguration = (section?: string) => { + if (section !== "kilo-code.new.autocomplete") { + return { + get: () => undefined, + inspect: () => undefined, + update: async () => {}, + } + } + return { + get: (key: string, fallback?: unknown) => { + const e = state.get(key) + return e?.workspaceValue ?? e?.globalValue ?? fallback + }, + inspect: (key: string) => state.get(key) ?? {}, + update: async (key: string, value: unknown, target: unknown) => { + // vscode.ConfigurationTarget.Global = 1, Workspace = 2 + const scope: keyof Scoped = target === 2 ? "workspaceValue" : "globalValue" + const e = entry(key) + if (value === undefined) delete e[scope] + else e[scope] = value + }, + } + } +} + +function setGlobal(state: State, key: string, value: unknown) { + const e = state.get(key) ?? {} + e.globalValue = value + state.set(key, e) +} + +function setWorkspace(state: State, key: string, value: unknown) { + const e = state.get(key) ?? {} + e.workspaceValue = value + state.set(key, e) +} + +afterEach(() => { + ;(vscode.workspace as unknown as Stub).getConfiguration = original as Stub["getConfiguration"] +}) + +describe("migrateDefaultAutocompleteSettings", () => { + let state: State + + beforeEach(() => { + state = new Map() + stubConfig(state) + }) + + it("clears provider/model when both equal the current default at global scope", async () => { + setGlobal(state, "provider", DEFAULT_AUTOCOMPLETE_MODEL.providerID) + setGlobal(state, "model", DEFAULT_AUTOCOMPLETE_MODEL.modelID) + const { context, flag } = makeContext() + + await migrateDefaultAutocompleteSettings(context) + + expect(state.get("provider")?.globalValue).toBeUndefined() + expect(state.get("model")?.globalValue).toBeUndefined() + expect(flag.get("kilo.autocomplete.defaultClearMigrationV1")).toBe(true) + }) + + it("leaves an explicitly chosen non-default model untouched", async () => { + setGlobal(state, "provider", "inception") + setGlobal(state, "model", "mercury-edit-2") + const { context, flag } = makeContext() + + await migrateDefaultAutocompleteSettings(context) + + expect(state.get("provider")?.globalValue).toBe("inception") + expect(state.get("model")?.globalValue).toBe("mercury-edit-2") + expect(flag.get("kilo.autocomplete.defaultClearMigrationV1")).toBe(true) + }) + + it("leaves a partial match untouched", async () => { + setGlobal(state, "provider", DEFAULT_AUTOCOMPLETE_MODEL.providerID) + setGlobal(state, "model", "inception/mercury-edit-2") + const { context } = makeContext() + + await migrateDefaultAutocompleteSettings(context) + + expect(state.get("provider")?.globalValue).toBe(DEFAULT_AUTOCOMPLETE_MODEL.providerID) + expect(state.get("model")?.globalValue).toBe("inception/mercury-edit-2") + }) + + it("ignores workspace-scoped pins so they aren't mistaken for global defaults", async () => { + setWorkspace(state, "provider", DEFAULT_AUTOCOMPLETE_MODEL.providerID) + setWorkspace(state, "model", DEFAULT_AUTOCOMPLETE_MODEL.modelID) + const { context } = makeContext() + + await migrateDefaultAutocompleteSettings(context) + + // Workspace value is intact — we only clear at global scope. + expect(state.get("provider")?.workspaceValue).toBe(DEFAULT_AUTOCOMPLETE_MODEL.providerID) + expect(state.get("model")?.workspaceValue).toBe(DEFAULT_AUTOCOMPLETE_MODEL.modelID) + }) + + it("only runs once per machine", async () => { + setGlobal(state, "provider", DEFAULT_AUTOCOMPLETE_MODEL.providerID) + setGlobal(state, "model", DEFAULT_AUTOCOMPLETE_MODEL.modelID) + const { context } = makeContext({ "kilo.autocomplete.defaultClearMigrationV1": true }) + + await migrateDefaultAutocompleteSettings(context) + + // Setting was preserved — second run is a no-op. + expect(state.get("provider")?.globalValue).toBe(DEFAULT_AUTOCOMPLETE_MODEL.providerID) + expect(state.get("model")?.globalValue).toBe(DEFAULT_AUTOCOMPLETE_MODEL.modelID) + }) + + it("sets the flag even when nothing needed clearing", async () => { + const { context, flag } = makeContext() + + await migrateDefaultAutocompleteSettings(context) + + expect(flag.get("kilo.autocomplete.defaultClearMigrationV1")).toBe(true) + }) +}) diff --git a/packages/kilo-vscode/tests/unit/autocomplete-settings-message.test.ts b/packages/kilo-vscode/tests/unit/autocomplete-settings-message.test.ts new file mode 100644 index 00000000000..3d24e8c9246 --- /dev/null +++ b/packages/kilo-vscode/tests/unit/autocomplete-settings-message.test.ts @@ -0,0 +1,85 @@ +import { describe, it, expect, afterEach, beforeEach } from "bun:test" +import * as vscode from "vscode" +import { buildAutocompleteSettingsMessage, validAutocompleteSetting } from "../../src/services/autocomplete/settings" + +type Stub = { + getConfiguration: (section?: string) => { + get: (key: string, fallback?: T) => T | undefined + update?: (key: string, value: unknown) => Promise + } +} + +const original = vscode.workspace.getConfiguration + +function stubConfig(state: Map) { + ;(vscode.workspace as unknown as Stub).getConfiguration = (section?: string) => { + if (section !== "kilo-code.new.autocomplete") { + return { get: (_key: string, fallback?: T) => fallback } + } + return { + get: (key: string, fallback?: T) => (state.has(key) ? (state.get(key) as T) : fallback), + } + } +} + +afterEach(() => { + ;(vscode.workspace as unknown as Stub).getConfiguration = original as Stub["getConfiguration"] +}) + +describe("buildAutocompleteSettingsMessage", () => { + let state: Map + + beforeEach(() => { + state = new Map() + stubConfig(state) + }) + + it("returns null for both keys when nothing is set so the webview renders 'Not set'", () => { + const msg = buildAutocompleteSettingsMessage() + + expect(msg.settings.provider).toBeNull() + expect(msg.settings.model).toBeNull() + }) + + it("passes an explicit BYOK selection through verbatim", () => { + state.set("provider", "inception") + state.set("model", "mercury-edit-2") + + const msg = buildAutocompleteSettingsMessage() + + expect(msg.settings.provider).toBe("inception") + expect(msg.settings.model).toBe("mercury-edit-2") + }) + + it("does not coerce a bare model setting to a default — let the webview see what was stored", () => { + state.set("model", "mercury-edit-2") + + const msg = buildAutocompleteSettingsMessage() + + expect(msg.settings.provider).toBeNull() + expect(msg.settings.model).toBe("mercury-edit-2") + }) +}) + +describe("validAutocompleteSetting", () => { + it("accepts null/undefined for provider and model so the user can clear back to the default", () => { + expect(validAutocompleteSetting("provider", null)).toBe(true) + expect(validAutocompleteSetting("provider", undefined)).toBe(true) + expect(validAutocompleteSetting("model", null)).toBe(true) + expect(validAutocompleteSetting("model", undefined)).toBe(true) + }) + + it("accepts known providers and models", () => { + expect(validAutocompleteSetting("provider", "inception")).toBe(true) + expect(validAutocompleteSetting("model", "mercury-edit-2")).toBe(true) + }) + + it("rejects unknown providers and models", () => { + expect(validAutocompleteSetting("provider", "openrouter")).toBe(false) + expect(validAutocompleteSetting("model", "gpt-5")).toBe(false) + }) + + it("rejects non-boolean toggle updates", () => { + expect(validAutocompleteSetting("enableAutoTrigger", "true")).toBe(false) + }) +}) diff --git a/packages/kilo-vscode/tests/unit/connection-utils.test.ts b/packages/kilo-vscode/tests/unit/connection-utils.test.ts index c916af225a9..4a29c068831 100644 --- a/packages/kilo-vscode/tests/unit/connection-utils.test.ts +++ b/packages/kilo-vscode/tests/unit/connection-utils.test.ts @@ -46,6 +46,14 @@ describe("resolveEventSessionId", () => { expect(resolveEventSessionId(e, noLookup)).toBe("s4") }) + it("returns sessionID from session.turn.close", () => { + const e = event({ + type: "session.turn.close", + properties: { sessionID: "s-turn", reason: "interrupted" }, + }) + expect(resolveEventSessionId(e, noLookup)).toBe("s-turn") + }) + it("returns sessionID from message.updated and calls onMessageUpdated", () => { const e = event({ type: "message.updated", diff --git a/packages/kilo-vscode/tests/unit/kilo-provider-rename.test.ts b/packages/kilo-vscode/tests/unit/kilo-provider-rename.test.ts new file mode 100644 index 00000000000..a5d684bf71a --- /dev/null +++ b/packages/kilo-vscode/tests/unit/kilo-provider-rename.test.ts @@ -0,0 +1,56 @@ +import { describe, expect, it } from "bun:test" +import { renameSession } from "../../src/kilo-provider/rename-session" +import { SESSION_TITLE_LIMIT } from "../../src/shared/session-title" + +type Params = { sessionID: string; directory?: string; title?: string } + +function client() { + const calls: Params[] = [] + return { + calls, + value: { + session: { + update: async (params: Params) => { + calls.push(params) + return { + data: { + id: params.sessionID, + title: params.title, + time: { created: 1, updated: 2 }, + }, + } + }, + }, + }, + } +} + +describe("renameSession", () => { + it("normalizes and persists a valid title through the backend client", async () => { + const api = client() + + const updated = await renameSession({ + client: api.value as never, + sessionID: "ses_1", + title: " Rename active session ", + directory: "/repo", + }) + + expect(api.calls).toHaveLength(1) + expect(api.calls[0]).toEqual({ sessionID: "ses_1", directory: "/repo", title: "Rename active session" }) + expect(updated.title).toBe("Rename active session") + }) + + it("rejects unsafe titles before they reach the backend", async () => { + const api = client() + const input = [" ", "a".repeat(SESSION_TITLE_LIMIT + 1), "Title\nSecond line", "Title\u202espoof"] + + for (const title of input) { + await expect( + renameSession({ client: api.value as never, sessionID: "ses_1", title, directory: "/repo" }), + ).rejects.toThrow("Invalid session title") + } + + expect(api.calls).toEqual([]) + }) +}) diff --git a/packages/kilo-vscode/tests/unit/kilo-provider-utils.test.ts b/packages/kilo-vscode/tests/unit/kilo-provider-utils.test.ts index d54327ad3ed..ef4aa2ab749 100644 --- a/packages/kilo-vscode/tests/unit/kilo-provider-utils.test.ts +++ b/packages/kilo-vscode/tests/unit/kilo-provider-utils.test.ts @@ -21,6 +21,7 @@ import type { EventMessagePartUpdated, EventMessageUpdated, EventSessionStatus, + EventSessionTurnClose, EventPermissionAsked, EventPermissionReplied, EventTodoUpdated, @@ -309,6 +310,16 @@ describe("mapSSEEventToWebviewMessage", () => { } }) + it("maps session.turn.close to its terminal reason", () => { + const event: EventSessionTurnClose = { + id: "evt-turn", + type: "session.turn.close", + properties: { sessionID: "sess-1", reason: "interrupted" }, + } + const msg = mapSSEEventToWebviewMessage(event, "sess-1") + expect(msg).toEqual({ type: "sessionTurnClosed", sessionID: "sess-1", reason: "interrupted" }) + }) + it("maps permission.asked to permissionRequest", () => { const event: EventPermissionAsked = { type: "permission.asked", diff --git a/packages/kilo-vscode/tests/unit/session-outcome.test.ts b/packages/kilo-vscode/tests/unit/session-outcome.test.ts new file mode 100644 index 00000000000..8c4397b98ef --- /dev/null +++ b/packages/kilo-vscode/tests/unit/session-outcome.test.ts @@ -0,0 +1,80 @@ +import { describe, expect, it } from "bun:test" +import { terminal } from "../../webview-ui/src/context/session-outcome" +import type { Message, TodoItem } from "../../webview-ui/src/types/messages" + +function message(finish?: string, error?: Message["error"]): Message { + return { + id: "m1", + sessionID: "s1", + role: "assistant", + createdAt: new Date(0).toISOString(), + finish, + error, + } +} + +function todo(status: TodoItem["status"]): TodoItem { + return { id: status, content: status, status } +} + +describe("terminal", () => { + it("returns no terminal state before a turn closes", () => { + expect(terminal({ messages: [message("stop")], todos: [] })).toBeUndefined() + }) + + it("hides normal completed turns", () => { + expect(terminal({ reason: "completed", messages: [message("stop")], todos: [] })).toBeUndefined() + }) + + it("warns when a completed turn leaves to-dos unfinished", () => { + expect( + terminal({ reason: "completed", messages: [message("stop")], todos: [todo("completed"), todo("pending")] }), + ).toEqual({ kind: "incomplete", tone: "warning", finish: "stop", remaining: 1 }) + }) + + it("treats cancelled to-dos as terminal rather than remaining work", () => { + expect(terminal({ reason: "completed", messages: [message("stop")], todos: [todo("cancelled")] })).toBeUndefined() + }) + + it("surfaces response limit and unknown model finishes before generic incomplete status", () => { + expect(terminal({ reason: "completed", messages: [message("length")], todos: [todo("pending")] })?.kind).toBe( + "limit", + ) + expect(terminal({ reason: "completed", messages: [message("unknown")], todos: [] })?.kind).toBe("unknown") + }) + + it("surfaces filtered and unexpected provider finishes", () => { + expect(terminal({ reason: "completed", messages: [message("content-filter")], todos: [] })?.kind).toBe("filtered") + expect(terminal({ reason: "completed", messages: [message("other")], todos: [] })?.kind).toBe("unexpected") + }) + + it("surfaces interruption and failures without a rendered error", () => { + expect(terminal({ reason: "interrupted", messages: [message("stop")], todos: [todo("pending")] })).toEqual({ + kind: "interrupted", + tone: "warning", + finish: "stop", + remaining: 1, + }) + expect(terminal({ reason: "error", messages: [message("error")], todos: [] })?.kind).toBe("error") + }) + + it("does not duplicate a concrete rendered failure", () => { + expect(terminal({ reason: "error", messages: [message("error", { name: "APIError" })], todos: [] })).toBeUndefined() + }) + + it("retains a fallback failure when the concrete error is hidden", () => { + expect( + terminal({ + reason: "error", + messages: [message("error", { name: "APIError" })], + todos: [], + hidden: () => true, + })?.kind, + ).toBe("error") + }) + + it("reports only the latest assistant finish reason", () => { + const user: Message = { id: "u1", sessionID: "s1", role: "user", createdAt: new Date(1).toISOString() } + expect(terminal({ reason: "completed", messages: [message("length"), user], todos: [] })?.finish).toBeUndefined() + }) +}) diff --git a/packages/kilo-vscode/tests/unit/session-queue.test.ts b/packages/kilo-vscode/tests/unit/session-queue.test.ts index 5d15ac66282..40d217662c9 100644 --- a/packages/kilo-vscode/tests/unit/session-queue.test.ts +++ b/packages/kilo-vscode/tests/unit/session-queue.test.ts @@ -2,11 +2,12 @@ import { describe, expect, it } from "bun:test" import { activeUserMessageID, messageTurns, + partitionTurns, queuedUserMessageIDs, stableMessageTurns, visibleMessages, } from "../../webview-ui/src/context/session-queue" -import type { Message } from "../../webview-ui/src/types/messages" +import type { Message, SessionStatusInfo } from "../../webview-ui/src/types/messages" const base = { sessionID: "session", @@ -24,6 +25,15 @@ const assistant = (id: string, parentID: string, opts: Partial = {}): M ...opts, }) +const layout = (messages: Message[], status: SessionStatusInfo, boundary?: string) => { + const active = activeUserMessageID(messages, status) + return partitionTurns( + messageTurns(messages, boundary), + new Set(active ? [active] : []), + new Set(queuedUserMessageIDs(messages, status)), + ) +} + describe("queuedUserMessageIDs", () => { it("keeps follow-ups queued before the first assistant exists", () => { const messages = [user("message_1"), user("message_2")] @@ -63,6 +73,12 @@ describe("queuedUserMessageIDs", () => { expect(queuedUserMessageIDs(messages, { type: "busy" })).toEqual(["message_3", "message_4"]) }) + it("queues loaded follow-ups after an active partial turn whose parent is outside the page", () => { + const messages = [assistant("message_2", "message_1", { finish: "tool-calls" }), user("message_3")] + + expect(queuedUserMessageIDs(messages, { type: "busy" })).toEqual(["message_3"]) + }) + it("returns no queued messages while idle", () => { const messages = [user("message_1"), user("message_2")] @@ -70,6 +86,150 @@ describe("queuedUserMessageIDs", () => { }) }) +describe("partitionTurns", () => { + it("renders the streaming turn outside virtual history", () => { + const messages = [ + user("message_1"), + assistant("message_2", "message_1", { finish: "stop" }), + user("message_3"), + assistant("message_4", "message_3", { finish: "tool-calls" }), + ] + const result = layout(messages, { type: "busy" }) + + expect(result.virtual.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_3"]) + expect(result.queued).toEqual([]) + }) + + it("renders a streaming partial turn directly when its parent is outside the loaded page", () => { + const result = layout([assistant("message_2", "message_1", { finish: "tool-calls" })], { type: "busy" }) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued).toEqual([]) + }) + + it("keeps an active partial turn direct when later loaded prompts are queued", () => { + const result = layout([assistant("message_2", "message_1", { finish: "tool-calls" }), user("message_3")], { + type: "busy", + }) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_3"]) + }) + + it("keeps an active partial direct when its update arrives after a queued prompt", () => { + const result = layout([user("message_3"), assistant("message_2", "message_1", { finish: "tool-calls" })], { + type: "busy", + }) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_3"]) + }) + + it("keeps queued prompts after the directly rendered active turn", () => { + const messages = [ + user("message_1"), + assistant("message_2", "message_1", { finish: "tool-calls" }), + user("message_3"), + user("message_4"), + ] + const result = layout(messages, { type: "busy" }) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_3", "message_4"]) + }) + + it("renders the first pending user turn directly before assistant output exists", () => { + const result = layout([user("message_1"), user("message_2")], { type: "busy" }) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_2"]) + }) + + it("moves a completed turn into history when the next queued turn becomes active at the bottom", () => { + const messages = [ + user("message_1"), + assistant("message_2", "message_1", { finish: "stop" }), + user("message_3"), + user("message_4"), + ] + const result = layout(messages, { type: "busy" }) + + expect(result.virtual.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_3"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_4"]) + }) + + it("retains completed and newly active tail turns directly during a paused queued handoff", () => { + const turns = messageTurns([ + user("message_1"), + assistant("message_2", "message_1", { finish: "stop" }), + user("message_3"), + user("message_4"), + ]) + const result = partitionTurns(turns, new Set(["message_1", "message_3"]), new Set(["message_4"])) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1", "message_3"]) + expect(result.queued.map((turn) => turn.user.id)).toEqual(["message_4"]) + }) + + it("returns completed idle turns to virtual history", () => { + const result = layout([user("message_1"), assistant("message_2", "message_1", { finish: "stop" })], { + type: "idle", + }) + + expect(result.virtual.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.direct).toEqual([]) + expect(result.queued).toEqual([]) + }) + + it("can retain a completed tail directly while its reading position is paused", () => { + const turns = messageTurns([user("message_1"), assistant("message_2", "message_1", { finish: "stop" })]) + const result = partitionTurns(turns, new Set(["message_1"]), new Set()) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.queued).toEqual([]) + }) + + it("preserves order when a retained turn has later visible prompts", () => { + const turns = messageTurns([user("message_1"), user("message_2")]) + const result = partitionTurns(turns, new Set(["message_1"]), new Set()) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1", "message_2"]) + expect(result.queued).toEqual([]) + }) + + it("keeps a paused completed turn direct when idle leaves a later prompt visible", () => { + const turns = messageTurns([ + user("message_1"), + assistant("message_2", "message_1", { finish: "stop" }), + user("message_3"), + ]) + const result = partitionTurns(turns, new Set(["message_1"]), new Set()) + + expect(result.virtual).toEqual([]) + expect(result.direct.map((turn) => turn.user.id)).toEqual(["message_1", "message_3"]) + expect(result.queued).toEqual([]) + }) + + it("does not render an active turn hidden by a revert boundary", () => { + const messages = [user("message_1"), assistant("message_2", "message_1", { finish: "stop" }), user("message_3")] + const result = layout(messages, { type: "busy" }, "message_3") + + expect(result.virtual.map((turn) => turn.user.id)).toEqual(["message_1"]) + expect(result.direct).toEqual([]) + expect(result.queued).toEqual([]) + }) +}) + describe("messageTurns", () => { it("attaches assistant output to its parent turn when queued users are newer", () => { const messages = [ @@ -109,6 +269,17 @@ describe("messageTurns", () => { ]) }) + it("keeps a parented assistant partial separate when its update follows newer loaded users", () => { + const turns = messageTurns([user("message_3"), assistant("message_2", "message_1")]) + + expect( + turns.map((turn) => ({ id: turn.id, partial: turn.partial, assistant: turn.assistant.map((msg) => msg.id) })), + ).toEqual([ + { id: "message_1", partial: true, assistant: ["message_2"] }, + { id: "message_3", partial: undefined, assistant: [] }, + ]) + }) + it("stops at the revert boundary user turn", () => { const messages = [ user("message_1"), @@ -179,6 +350,12 @@ describe("activeUserMessageID", () => { expect(activeUserMessageID(messages, { type: "busy" })).toBe("message_1") }) + it("uses a streaming partial turn whose parent is outside the loaded page", () => { + const messages = [assistant("message_2", "message_1", { finish: "tool-calls" })] + + expect(activeUserMessageID(messages, { type: "busy" })).toBe("message_1") + }) + it("ignores terminal assistant updates without completed timestamps", () => { const messages = [user("message_1"), assistant("message_2", "message_1", { finish: "stop" }), user("message_3")] diff --git a/packages/kilo-vscode/tests/unit/session-title.test.ts b/packages/kilo-vscode/tests/unit/session-title.test.ts new file mode 100644 index 00000000000..5c2b5828f9d --- /dev/null +++ b/packages/kilo-vscode/tests/unit/session-title.test.ts @@ -0,0 +1,47 @@ +import { describe, expect, it } from "bun:test" +import { parseSessionTitle, SESSION_TITLE_LIMIT } from "../../src/shared/session-title" + +describe("parseSessionTitle", () => { + it("rejects non-string input from untrusted callers", () => { + expect(parseSessionTitle(null)).toEqual({ error: "invalid" }) + }) + + it("trims a valid title", () => { + expect(parseSessionTitle(" Review authentication flow ")).toEqual({ value: "Review authentication flow" }) + }) + + it("rejects empty titles", () => { + expect(parseSessionTitle(" \t \n ")).toEqual({ error: "required" }) + }) + + it("accepts the display limit and rejects longer titles", () => { + expect(parseSessionTitle("a".repeat(SESSION_TITLE_LIMIT))).toEqual({ value: "a".repeat(SESSION_TITLE_LIMIT) }) + expect(parseSessionTitle("a".repeat(SESSION_TITLE_LIMIT + 1))).toEqual({ error: "too_long" }) + }) + + it("rejects every blocked control and directional formatting range", () => { + const values = [ + "Task\u0000suffix", + "Task\u001bsuffix", + "Task\u001fsuffix", + "Task\u007fsuffix", + "Task\u009fsuffix", + "Task\u061csuffix", + "Task\u200esuffix", + "Task\u200fsuffix", + "Task\u2028suffix", + "Task\u2029suffix", + "Task\u202asuffix", + "Task\u202esuffix", + "Task\u2066suffix", + "Task\u2069suffix", + ] + for (const value of values) expect(parseSessionTitle(value)).toEqual({ error: "control" }) + }) + + it("accepts normal unicode display text", () => { + expect(parseSessionTitle("Analyse de la session - \u4fee\u6b63")).toEqual({ + value: "Analyse de la session - \u4fee\u6b63", + }) + }) +}) diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/ErrorDisplay.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/ErrorDisplay.tsx index ef600bccfc3..52ae08d88e6 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/ErrorDisplay.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/ErrorDisplay.tsx @@ -3,6 +3,7 @@ import { Card } from "@kilocode/kilo-ui/card" import { Collapsible } from "@kilocode/kilo-ui/collapsible" import { useDialog } from "@kilocode/kilo-ui/context/dialog" import { ErrorDetails } from "@kilocode/kilo-ui/error-details" +import { Icon } from "@kilocode/kilo-ui/icon" import { Button } from "@kilocode/kilo-ui/button" import type { AssistantMessage } from "@kilocode/sdk/v2" import { useLanguage } from "../../context/language" @@ -62,8 +63,11 @@ export const ErrorDisplay: Component = (props) => { return ( - {errorText()} + +
+ +
{errorText()}
+
{t("error.details.show")} diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx index 9bd1da67bfe..702bd3a680e 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/MessageList.tsx @@ -25,12 +25,14 @@ import { RevertBanner } from "./RevertBanner" import { AccountSwitcher } from "../shared/AccountSwitcher" import { KiloNotifications } from "./KiloNotifications" import { WorkingIndicator } from "../shared/WorkingIndicator" +import { TurnOutcome } from "../shared/TurnOutcome" import { QuestionDock } from "./QuestionDock" import { Virtualizer } from "virtua/solid" import { SuggestBar } from "./SuggestBar" import { activeUserMessageID as getActiveUserMessageID, messageTurns, + partitionTurns, queuedUserMessageIDs, stableMessageTurns, type MessageTurn, @@ -98,14 +100,40 @@ export const MessageList: Component = (props) => { const activeUserID = createMemo(() => getActiveUserMessageID(session.messages(), session.statusInfo())) const queuedIDs = createMemo(() => new Set(queuedUserMessageIDs(session.messages(), session.statusInfo()))) - const visibleTurns = createMemo(() => turns().filter((turn) => !queuedIDs().has(turn.user.id))) - const queuedTurns = createMemo(() => turns().filter((turn) => queuedIDs().has(turn.user.id))) - - const activeUserIndex = createMemo(() => { - const active = activeUserID() - if (!active) return -1 - return visibleTurns().findIndex((turn) => turn.user.id === active) + const [held, setHeld] = createSignal<{ sid: string; ids: Set }>() + createEffect(() => { + const id = activeUserID() + const sid = session.currentSessionID() + const paused = autoScroll.userScrolled() + if (!sid || (!id && !paused)) { + setHeld(undefined) + return + } + if (!id) return + if (!paused) { + setHeld({ sid, ids: new Set([id]) }) + return + } + setHeld((prev) => { + if (prev?.sid === sid && prev.ids.has(id)) return prev + const ids = prev?.sid === sid ? new Set(prev.ids) : new Set() + ids.add(id) + return { sid, ids } + }) }) + const directIDs = createMemo(() => { + const item = held() + const ids = item && item.sid === session.currentSessionID() ? new Set(item.ids) : new Set() + const active = activeUserID() + if (active) ids.add(active) + return ids + }) + // Keep the growing live turn out of Virtua. Resizing a tall virtual item while + // the user reads within it makes Virtua compensate scrollTop as if earlier + // content moved, dragging the viewport downward during streaming. Preserve + // direct-rendered tail turns while paused so completion and queue handoffs do + // not move a turn being read back into the virtualized history. + const partition = createMemo(() => partitionTurns(turns(), directIDs(), queuedIDs())) const save = (id: string | undefined) => { const el = scrollEl() @@ -227,30 +255,30 @@ export const MessageList: Component = (props) => { {language.t("session.messages.loadEarlier")} - - - {(turn, index) => { - const queued = createMemo(() => { - const active = activeUserIndex() - if (active === -1) return false - return index() > active - }) - - return - }} - + 0 || partition().direct.length > 0}> +
+ 0}> + + {(turn) => } + + + + {(turn) => } + +
- {(turn) => } + {(turn) => } + {(req) => } {(req) => }
diff --git a/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx b/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx index 6360660cce3..d4409d07473 100644 --- a/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/chat/TaskHeader.tsx @@ -8,7 +8,7 @@ * session activity) and a context window progress bar. */ -import { Component, For, Show, createMemo, createSignal, onMount, onCleanup } from "solid-js" +import { Component, For, Show, createMemo, createSignal, createEffect, onMount, onCleanup } from "solid-js" import { IconButton } from "@kilocode/kilo-ui/icon-button" import { Tooltip } from "@kilocode/kilo-ui/tooltip" import { Icon } from "@kilocode/kilo-ui/icon" @@ -19,6 +19,7 @@ import { useLanguage } from "../../context/language" import { useVSCode } from "../../context/vscode" import { TaskTimeline } from "./TaskTimeline" import { ContextProgress } from "./ContextProgress" +import { SessionRenameEditor } from "../shared/SessionRenameEditor" import { target as todoTarget } from "../../context/todo-revert" import type { Part, TodoItem, ExtensionMessage } from "../../types/messages" @@ -31,6 +32,7 @@ export const TaskHeader: Component = (props) => { const language = useLanguage() const title = createMemo(() => session.currentSession()?.title ?? language.t("command.session.new")) + const canRename = createMemo(() => !props.readonly && !!session.currentSession()) const hasMessages = createMemo(() => session.messages().length > 0) const busy = createMemo(() => session.status() === "busy") const canCompact = createMemo(() => !busy() && session.visibleMessages().length > 0 && !!session.selected()) @@ -114,6 +116,31 @@ export const TaskHeader: Component = (props) => { }) const [todosOpen, setTodosOpen] = createSignal(false) + const [renaming, setRenaming] = createSignal<{ id: string; title: string }>() + + const startRename = () => { + if (props.readonly) return + const info = session.currentSession() + if (!info) return + setRenaming({ id: info.id, title: info.title ?? "" }) + } + + const commitRename = (title: string) => { + const info = renaming() + if (!info) return + setRenaming(undefined) + if (title === info.title) return + session.renameSession(info.id, title) + } + + const cancelRename = () => { + setRenaming(undefined) + } + + createEffect(() => { + const info = renaming() + if (info && session.currentSession()?.id !== info.id) setRenaming(undefined) + }) const donePart = (idx: number): Part | undefined => todoTarget({ messages: session.messages(), parts: session.allParts() }, idx) @@ -128,8 +155,34 @@ export const TaskHeader: Component = (props) => { return (
-
- {title()} +
+ + } + > + { + if (!canRename() || (e.key !== "Enter" && e.key !== " ")) return + e.preventDefault() + startRename() + }} + > + {title()} + +
diff --git a/packages/kilo-vscode/webview-ui/src/components/history/SessionList.tsx b/packages/kilo-vscode/webview-ui/src/components/history/SessionList.tsx index 7a99fa4e48a..6a0cbed69d4 100644 --- a/packages/kilo-vscode/webview-ui/src/components/history/SessionList.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/history/SessionList.tsx @@ -11,12 +11,12 @@ import { ContextMenu } from "@kilocode/kilo-ui/context-menu" import { Dialog } from "@kilocode/kilo-ui/dialog" import { Button } from "@kilocode/kilo-ui/button" import { IconButton } from "@kilocode/kilo-ui/icon-button" -import { InlineInput } from "@kilocode/kilo-ui/inline-input" import { useDialog } from "@kilocode/kilo-ui/context/dialog" import { useSession } from "../../context/session" import { useLanguage } from "../../context/language" import { formatRelativeDate } from "../../utils/date" import type { SessionInfo } from "../../types/messages" +import { SessionRenameEditor } from "../shared/SessionRenameEditor" const DATE_GROUP_KEYS = ["time.today", "time.yesterday", "time.thisWeek", "time.thisMonth", "time.older"] as const @@ -46,7 +46,7 @@ const SessionList: Component = (props) => { const dialog = useDialog() const [renamingId, setRenamingId] = createSignal(null) - const [renameValue, setRenameValue] = createSignal("") + const [pendingRenameId, setPendingRenameId] = createSignal(null) onMount(() => { console.log("[Kilo New] SessionList mounted, loading sessions") @@ -60,27 +60,18 @@ const SessionList: Component = (props) => { function startRename(s: SessionInfo) { setRenamingId(s.id) - setRenameValue(s.title || "") } - function saveRename() { + function saveRename(title: string) { const id = renamingId() - const title = renameValue().trim() - if (!id || !title) { - cancelRename() - return - } + if (!id) return const existing = session.sessions().find((s) => s.id === id) - if (!existing || title !== (existing.title || "")) { - session.renameSession(id, title) - } + if (!existing || title !== (existing.title || "")) session.renameSession(id, title) setRenamingId(null) - setRenameValue("") } function cancelRename() { setRenamingId(null) - setRenameValue("") } function confirmDelete(s: SessionInfo) { @@ -115,8 +106,16 @@ const SessionList: Component = (props) => { {node} - - startRename(item)}> + { + if (pendingRenameId() !== item.id) return + event.preventDefault() + setPendingRenameId(null) + startRename(item) + }} + > + setPendingRenameId(item.id)}> {language.t("common.rename")} session.exportSessionTranscript(item.id)}> @@ -161,7 +160,16 @@ const SessionList: Component = (props) => { {s.title || language.t("session.untitled")} {formatRelativeDate(s.updatedAt)} { + e.stopPropagation() + startRename(s) + }} + > + + + { e.stopPropagation() confirmDelete(s) @@ -177,24 +185,7 @@ const SessionList: Component = (props) => { } > - requestAnimationFrame(() => el?.focus())} - value={renameValue()} - onInput={(e) => setRenameValue(e.currentTarget.value)} - onKeyDown={(e) => { - e.stopPropagation() - if (e.key === "Enter") { - e.preventDefault() - saveRename() - } - if (e.key === "Escape") { - e.preventDefault() - cancelRename() - } - }} - onBlur={() => saveRename()} - style={{ width: "100%" }} - /> + )} diff --git a/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceListView.tsx b/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceListView.tsx index 62ea13eed68..8bb615fa386 100644 --- a/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceListView.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceListView.tsx @@ -23,7 +23,7 @@ interface Props { items: MarketplaceItem[] metadata: MarketplaceInstalledMetadata fetching: boolean - type: "mcp" | "mode" | "skill" + type: "mcp" | "agent" | "skill" searchPlaceholder: string emptyMessage: string onInstall: (item: MarketplaceItem) => void diff --git a/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceView.tsx b/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceView.tsx index 295b081bd78..b8deefc54e3 100644 --- a/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceView.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/marketplace/MarketplaceView.tsx @@ -9,7 +9,7 @@ import { useDialog } from "@kilocode/kilo-ui/context/dialog" import type { MarketplaceItem, McpMarketplaceItem, - ModeMarketplaceItem, + AgentMarketplaceItem, SkillMarketplaceItem, MarketplaceInstalledMetadata, } from "../../types/marketplace" @@ -31,12 +31,13 @@ export const MarketplaceView = () => { const [metadata, setMetadata] = createSignal(EMPTY_METADATA) const [fetching, setFetching] = createSignal(true) const [errors, setErrors] = createSignal([]) - const [tab, setTab] = createSignal("mcp") + const [tab, setTab] = createSignal("agent") const [pending, setPending] = createSignal<{ item: MarketplaceItem; scope: "project" | "global" } | null>(null) + const [showMigrationBanner, setShowMigrationBanner] = createSignal(false) const skills = createMemo(() => items().filter((i): i is SkillMarketplaceItem => i.type === "skill")) const mcps = createMemo(() => items().filter((i): i is McpMarketplaceItem => i.type === "mcp")) - const modes = createMemo(() => items().filter((i): i is ModeMarketplaceItem => i.type === "mode")) + const agents = createMemo(() => items().filter((i): i is AgentMarketplaceItem => i.type === "agent")) const fetchData = () => { setFetching(true) @@ -51,6 +52,7 @@ export const MarketplaceView = () => { setMetadata(msg.marketplaceInstalledMetadata ?? EMPTY_METADATA) setErrors(msg.errors ?? []) setFetching(false) + setShowMigrationBanner(msg.showAgentMigrationBanner ?? false) } if (msg.type === "marketplaceRemoveResult") { const removed = pending() @@ -138,6 +140,11 @@ export const MarketplaceView = () => { setErrors((prev) => prev.filter((_, i) => i !== idx)) } + const dismissMigrationBanner = () => { + setShowMigrationBanner(false) + vscode.postMessage({ type: "dismissAgentMigrationBanner" }) + } + return (
0}> @@ -153,18 +160,26 @@ export const MarketplaceView = () => { + {t("marketplace.tab.agents")} {t("marketplace.tab.mcp")} - {t("marketplace.tab.modes")} {t("marketplace.tab.skills")}
- + + + + {t("marketplace.migration.notice")} + + + { /> - + { const typeName = () => { if (props.item.type === "mcp") return t("marketplace.remove.type.mcp") - if (props.item.type === "mode") return t("marketplace.remove.type.mode") + if (props.item.type === "agent") return t("marketplace.remove.type.agent") return t("marketplace.remove.type.skill") } return ( -

{t("marketplace.remove.confirm", { type: typeName(), scope: t(`marketplace.scope.${props.scope}`) })}

-
- - +
+ + {t("marketplace.remove.confirm", { type: typeName(), scope: t(`marketplace.scope.${props.scope}`) })} + +
+ + +
) diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx index 4dec1e271d8..dd61fa49405 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx @@ -200,9 +200,9 @@ const AgentBehaviourTab: Component = () => { const confirmRemoveMode = (agent: AgentInfo) => { dialog.show(() => ( - +
- {language.t("settings.agentBehaviour.removeMode.confirm", { name: agent.name })} + {language.t("settings.agentBehaviour.removeAgent.confirm", { name: agent.name })}
@@ -357,7 +357,7 @@ const AgentBehaviourTab: Component = () => { color: "var(--text-weak-base, var(--vscode-descriptionForeground))", }} > - {language.t("settings.agentBehaviour.noModesFound")} + {language.t("settings.agentBehaviour.noAgentsFound")}
} diff --git a/packages/kilo-vscode/webview-ui/src/components/settings/IndexingTab.tsx b/packages/kilo-vscode/webview-ui/src/components/settings/IndexingTab.tsx index 60cd1199fbc..188250c315c 100644 --- a/packages/kilo-vscode/webview-ui/src/components/settings/IndexingTab.tsx +++ b/packages/kilo-vscode/webview-ui/src/components/settings/IndexingTab.tsx @@ -1,10 +1,6 @@ import { Component, For, Show, createMemo, createSignal } from "solid-js" import { Card } from "@kilocode/kilo-ui/card" -import { - formatKiloEmbeddingModelLabel, - getKiloEmbeddingModel, - normalizeKiloEmbeddingModelId, -} from "@kilocode/kilo-indexing/embedding-models" +import { formatKiloEmbeddingModelLabel, getKiloEmbeddingModel } from "@kilocode/kilo-indexing/embedding-models" import { Select } from "@kilocode/kilo-ui/select" import { Switch } from "@kilocode/kilo-ui/switch" import { TextField } from "@kilocode/kilo-ui/text-field" @@ -96,16 +92,20 @@ const IndexingTab: Component = () => { } const vectorStore = () => cfg().vectorStore ?? "qdrant" - const kiloDefault = () => embeds.catalog().defaultModel + const kiloDefault = () => + getKiloEmbeddingModel(embeds.catalog().defaultModel, embeds.catalog())?.id ?? embeds.catalog().defaultModel const kiloModels = createMemo(() => embeds.catalog().models.map((model) => ({ value: model.id, label: formatKiloEmbeddingModelLabel(model), })), ) - const knownKiloModel = (model: string | undefined) => getKiloEmbeddingModel(model, embeds.catalog())?.id + const knownKiloModel = (model: string | null | undefined) => + getKiloEmbeddingModel(model ?? undefined, embeds.catalog())?.id + const kiloValue = () => knownKiloModel(cfg().model) ?? kiloDefault() const kiloAvailable = () => !!server.profileData() || provider.authStates()[KILO_PROVIDER_ID] !== undefined const selectedProvider = () => cfg().provider ?? (kiloAvailable() ? "kilo" : undefined) + const staleKiloModel = () => selectedProvider() === "kilo" && !!cfg().model && !knownKiloModel(cfg().model) const providers = createMemo(() => allProviders.filter((item) => item.value !== "kilo" || kiloAvailable() || selectedProvider() === "kilo"), ) @@ -113,15 +113,15 @@ const IndexingTab: Component = () => { const saveProvider = (next: ProviderId | undefined) => { if (next === "kilo") { - const model = knownKiloModel(cfg().model) ?? (kiloDefault() || undefined) + const model = knownKiloModel(cfg().model) ?? (kiloDefault() || null) updateIndexing({ provider: next, model, - dimension: undefined, + dimension: null, }) return } - updateIndexing({ provider: next, model: undefined, dimension: undefined }) + updateIndexing({ provider: next, model: null, dimension: null }) } const saveEnabled = (enabled: boolean) => { @@ -129,7 +129,8 @@ const IndexingTab: Component = () => { updateIndexing({ enabled, provider: "kilo", - model: knownKiloModel(cfg().model) ?? kiloDefault(), + model: knownKiloModel(cfg().model) ?? (kiloDefault() || null), + dimension: null, }) return } @@ -142,7 +143,8 @@ const IndexingTab: Component = () => { indexing: { enabled, provider: "kilo", - model: knownKiloModel(cfg().model) ?? kiloDefault(), + model: knownKiloModel(cfg().model) ?? (kiloDefault() || null), + dimension: null, }, }) return @@ -151,15 +153,9 @@ const IndexingTab: Component = () => { } const saveModel = (value: string) => { + if (selectedProvider() === "kilo") return const trimmed = value.trim() - if (!trimmed) { - updateIndexing({ model: undefined }) - return - } - updateIndexing({ - model: - selectedProvider() === "kilo" ? (normalizeKiloEmbeddingModelId(trimmed, embeds.catalog()) ?? trimmed) : trimmed, - }) + updateIndexing({ model: trimmed || null }) } const providerValue = (group: string, key: string) => { @@ -189,13 +185,13 @@ const IndexingTab: Component = () => { } const saveNumber = ( - key: keyof IndexingConfig, + key: TuningKey | "dimension", value: string, options?: { integer?: boolean; min?: number; max?: number }, ) => { const trimmed = value.trim() if (!trimmed) { - updateIndexing({ [key]: undefined }) + updateIndexing({ [key]: key === "dimension" ? null : undefined }) return } @@ -272,35 +268,37 @@ const IndexingTab: Component = () => { >