Sfoglia il codice sorgente

Merge branch 'main' into roo-v3.38.3

Kevin van Dijk 1 mese fa
parent
commit
e0c1abb41b
100 ha cambiato i file con 2282 aggiunte e 423 eliminazioni
  1. 0 5
      .changeset/agent-manager-dropdown-ux.md
  2. 0 5
      .changeset/agent-manager-question-support.md
  3. 0 5
      .changeset/fix-mac-exit-message.md
  4. 0 5
      .changeset/mode-autocomplete.md
  5. 4 0
      .github/workflows/code-qa.yml
  6. 4 0
      .github/workflows/marketplace-publish.yml
  7. 14 47
      .kilocode/skills/translation/SKILL.md
  8. 22 0
      .kilocode/workflows/add-missing-translations.md
  9. 5 2
      .vscode/launch.json
  10. 24 1
      .vscode/tasks.json
  11. 34 3
      AGENTS.md
  12. 104 0
      CHANGELOG.md
  13. 2 0
      README.md
  14. 75 15
      apps/kilocode-docs/docs/advanced-usage/agent-manager.md
  15. 1 1
      apps/kilocode-docs/docs/advanced-usage/auto-cleanup.md
  16. 0 1
      apps/kilocode-docs/docs/advanced-usage/code-reviews.md
  17. 1 1
      apps/kilocode-docs/docs/advanced-usage/memory-bank.md
  18. 3 3
      apps/kilocode-docs/docs/advanced-usage/migrating-from-cursor-windsurf.md
  19. 154 0
      apps/kilocode-docs/docs/agent-behavior/agents-md.md
  20. 5 5
      apps/kilocode-docs/docs/agent-behavior/custom-instructions.md
  21. 0 0
      apps/kilocode-docs/docs/agent-behavior/custom-modes.md
  22. 4 4
      apps/kilocode-docs/docs/agent-behavior/custom-rules.md
  23. 1 1
      apps/kilocode-docs/docs/agent-behavior/prompt-engineering.md
  24. 57 59
      apps/kilocode-docs/docs/agent-behavior/skills.md
  25. 0 0
      apps/kilocode-docs/docs/agent-behavior/workflows.mdx
  26. 22 20
      apps/kilocode-docs/docs/basic-usage/autocomplete.md
  27. 1 1
      apps/kilocode-docs/docs/basic-usage/git-commit-generation.md
  28. 0 0
      apps/kilocode-docs/docs/basic-usage/settings-management.md
  29. 1 1
      apps/kilocode-docs/docs/basic-usage/using-modes.md
  30. 67 0
      apps/kilocode-docs/docs/contributing/architecture/annual-billing.md
  31. 2 2
      apps/kilocode-docs/docs/contributing/architecture/enterprise-mcp-controls.md
  32. 1 1
      apps/kilocode-docs/docs/contributing/architecture/feature-template.md
  33. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-org-user-install.png
  34. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-today.png
  35. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-with-ent-control.png
  36. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/organization-modes-library-1.png
  37. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/organization-modes-library-2.png
  38. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/track-repo-url-system-design.png
  39. 0 0
      apps/kilocode-docs/docs/contributing/architecture/img/voice-transcription-architecture.png
  40. 25 60
      apps/kilocode-docs/docs/contributing/architecture/index.md
  41. 2 2
      apps/kilocode-docs/docs/contributing/architecture/onboarding-engagement-improvements.md
  42. 2 2
      apps/kilocode-docs/docs/contributing/architecture/organization-modes-library.md
  43. 2 2
      apps/kilocode-docs/docs/contributing/architecture/security-reviews.md
  44. 2 2
      apps/kilocode-docs/docs/contributing/architecture/track-repo-url.md
  45. 77 0
      apps/kilocode-docs/docs/contributing/architecture/vercel-ai-gateway.md
  46. 2 2
      apps/kilocode-docs/docs/contributing/architecture/voice-transcription.md
  47. 3 3
      apps/kilocode-docs/docs/contributing/index.md
  48. 0 48
      apps/kilocode-docs/docs/contributing/specs/index.md
  49. 1 1
      apps/kilocode-docs/docs/faq.md
  50. 4 4
      apps/kilocode-docs/docs/features/api-configuration-profiles.md
  51. 1 1
      apps/kilocode-docs/docs/features/auto-launch-configuration.md
  52. 109 0
      apps/kilocode-docs/docs/features/mcp/using-mcp-in-cli.md
  53. 2 2
      apps/kilocode-docs/docs/features/model-temperature.md
  54. 6 6
      apps/kilocode-docs/docs/index.mdx
  55. 9 4
      apps/kilocode-docs/docs/providers/bedrock.md
  56. 2 1
      apps/kilocode-docs/docs/providers/cerebras.md
  57. 1 1
      apps/kilocode-docs/docs/tips-and-tricks.md
  58. 39 4
      apps/kilocode-docs/docusaurus.config.ts
  59. 4 4
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/custom-instructions.md
  60. 3 3
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/custom-rules.md
  61. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/memory-bank.md
  62. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/prompt-engineering.md
  63. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/basic-usage/git-commit-generation.md
  64. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/basic-usage/using-modes.md
  65. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/extending/contributing-to-kilo.md
  66. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/faq.md
  67. 5 5
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/features/api-configuration-profiles.md
  68. 2 2
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/features/model-temperature.md
  69. 6 6
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/index.mdx
  70. 1 1
      apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/tips-and-tricks.md
  71. 30 26
      apps/kilocode-docs/sidebars.ts
  72. 2 0
      apps/storybook/.storybook/preview.ts
  73. 43 0
      apps/storybook/src/decorators/withPostMessageMock.tsx
  74. 1 4
      apps/storybook/src/utils/createExtensionStateMock.ts
  75. 71 0
      apps/storybook/stories/KilocodeNotifications.stories.tsx
  76. 43 0
      apps/storybook/stories/MicrophoneButton.stories.tsx
  77. 48 0
      apps/storybook/stories/STTSetupPopover.stories.tsx
  78. 49 0
      cli/CHANGELOG.md
  79. 1 1
      cli/README.md
  80. 35 4
      cli/docs/DEVELOPMENT.md
  81. 18 1
      cli/esbuild.config.mjs
  82. 1 1
      cli/package.dist.json
  83. 2 2
      cli/package.json
  84. 109 0
      cli/src/__tests__/append-system-prompt.test.ts
  85. 14 18
      cli/src/auth/__tests__/device-auth.test.ts
  86. 4 0
      cli/src/cli.ts
  87. 113 0
      cli/src/commands/__tests__/condense.test.ts
  88. 2 0
      cli/src/commands/__tests__/helpers/mockContext.ts
  89. 43 0
      cli/src/commands/condense.ts
  90. 3 0
      cli/src/commands/core/types.ts
  91. 2 0
      cli/src/commands/index.ts
  92. 11 1
      cli/src/config/__tests__/persistence-provider-merge.test.ts
  93. 17 0
      cli/src/host/ExtensionHost.ts
  94. 5 0
      cli/src/index.ts
  95. 8 1
      cli/src/services/extension.ts
  96. 103 4
      cli/src/services/logs.ts
  97. 122 0
      cli/src/state/atoms/__tests__/cancelling.test.ts
  98. 328 0
      cli/src/state/atoms/__tests__/default-selection.test.ts
  99. 28 0
      cli/src/state/atoms/__tests__/extension-message-updates.test.ts
  100. 102 0
      cli/src/state/atoms/__tests__/keyboard.test.ts

+ 0 - 5
.changeset/agent-manager-dropdown-ux.md

@@ -1,5 +0,0 @@
----
-"@roo-code/vscode-webview": patch
----
-
-Improve Agent Manager run mode dropdown UX: close dropdown when clicking outside, add tooltip on hover

+ 0 - 5
.changeset/agent-manager-question-support.md

@@ -1,5 +0,0 @@
----
-"@roo-code/vscode-webview": patch
----
-
-Add follow-up question answer buttons to Agent Manager, allowing users to click suggestion buttons to respond to agent questions

+ 0 - 5
.changeset/fix-mac-exit-message.md

@@ -1,5 +0,0 @@
----
-"kilo-code": patch
----
-
-Fixed exit prompt showing "Cmd+C" instead of "Ctrl+C" on Mac. Ctrl+C is the universal terminal interrupt signal on all platforms.

+ 0 - 5
.changeset/mode-autocomplete.md

@@ -1,5 +0,0 @@
----
-"kilo-cli": minor
----
-
-Add autocomplete for `/mode` command in CLI, similar to model autocomplete. When typing `/mode ` and pressing tab, users now see suggestions for all available modes including default and custom modes with their names, descriptions, and source labels.

+ 4 - 0
.github/workflows/code-qa.yml

@@ -174,6 +174,10 @@ jobs:
                   check-latest: false
               env:
                   GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+            - name: Setup Gradle
+              uses: gradle/actions/setup-gradle@v4
+              with:
+                  cache-read-only: ${{ github.ref != 'refs/heads/main' }}
             - name: Install system dependencies
               run: |
                   sudo apt-get update

+ 4 - 0
.github/workflows/marketplace-publish.yml

@@ -189,6 +189,10 @@ jobs:
                   java-version: "21"
                   check-latest: false
                   token: ${{ secrets.GITHUB_TOKEN }}
+            - name: Setup Gradle
+              uses: gradle/actions/setup-gradle@v4
+              with:
+                  cache-read-only: false
             - name: Install system dependencies
               run: |
                   sudo apt-get update

+ 14 - 47
.roo/rules-translate/AGENTS.md → .kilocode/skills/translation/SKILL.md

@@ -1,17 +1,13 @@
-# AGENTS.md
-
-This file provides guidance to agents when working with code in this repository in Translate mode.
-
-## Workflow
-
-This workflow requires Orchestrator mode.
+---
+name: translation
+description: Guidelines for translating and localizing the Kilo Code extension, including language-specific rules for German, Simplified Chinese, and Traditional Chinese.
+---
 
-Execute `node scripts/find-missing-translations.js` in Code mode to find all missing translations.
+# Translation Guidelines
 
-For each language that is missing translations:
+This file provides guidance to agents when working with translations in this repository.
 
-- For each JSON file that is missing translations:
-    - Start a separate subtask in Translate mode for this language and JSON file to add the missing translations. Do not try to process mutliple languages or JSON files in one subtask.
+For the translation workflow, use the `/add-missing-translations` command or see `.kilocode/workflows/add-missing-translations.md`.
 
 ---
 
@@ -311,42 +307,13 @@ For each language that is missing translations:
 
 ### Common Patterns
 
-```markdown
-<<<<<<< BEFORE
-"dragFiles": "按住shift拖动文件"
-=======
-"dragFiles": "Shift+拖拽文件"
-
-> > > > > > > AFTER
-
-<<<<<<< BEFORE
-"description": "启用后,Kilo Code 将能够与 MCP 服务器交互以获取高级功能。"
-=======
-"description": "启用后 Kilo Code 可与 MCP 服务交互获取高级功能。"
-
-> > > > > > > AFTER
-
-<<<<<<< BEFORE
-"cannotUndo": "此操作无法撤消。"
-=======
-"cannotUndo": "此操作不可逆。"
-
-> > > > > > > AFTER
-
-<<<<<<< BEFORE
-"hold shift to drag in files" → "按住shift拖动文件"
-=======
-"hold shift to drag in files" → "Shift+拖拽文件"
-
-> > > > > > > AFTER
-
-<<<<<<< BEFORE
-"Double click to edit" → "双击进行编辑"
-=======
-"Double click to edit" → "双击编辑"
-
-> > > > > > > AFTER
-```
+| Original                        | Avoid                                                         | Preferred                                            |
+| ------------------------------- | ------------------------------------------------------------- | ---------------------------------------------------- |
+| `"dragFiles"`                   | `"按住shift拖动文件"`                                         | `"Shift+拖拽文件"`                                   |
+| `"description"`                 | `"启用后,Kilo Code 将能够与 MCP 服务器交互以获取高级功能。"` | `"启用后 Kilo Code 可与 MCP 服务交互获取高级功能。"` |
+| `"cannotUndo"`                  | `"此操作无法撤消。"`                                          | `"此操作不可逆。"`                                   |
+| `"hold shift to drag in files"` | `"按住shift拖动文件"`                                         | `"Shift+拖拽文件"`                                   |
+| `"Double click to edit"`        | `"双击进行编辑"`                                              | `"双击编辑"`                                         |
 
 ### Common Pitfalls
 

+ 22 - 0
.kilocode/workflows/add-missing-translations.md

@@ -0,0 +1,22 @@
+# Add missing translations
+
+This workflow requires Orchestrator mode.
+
+Execute `node scripts/find-missing-translations.js` in Code mode to find all missing translations.
+
+For each language that is missing translations:
+
+- For each JSON file that is missing translations:
+    - Start a separate subtask in Translate mode for this language and JSON file to add the missing translations. Do not try to process multiple languages or JSON files in one subtask.
+
+## Translation Guidelines
+
+When translating, follow these key rules:
+
+1. **Supported Languages**: ar, ca, cs, de, en, es, fr, hi, id, it, ja, ko, nl, pl, pt-BR, ru, th, tr, uk, vi, zh-CN, zh-TW
+2. **Voice**: Always use informal speech (e.g., "du" not "Sie" in German)
+3. **Technical Terms**: Don't translate "token", "API", "prompt" and domain-specific technical terms
+4. **Placeholders**: Keep `{{variable}}` placeholders exactly as in the English source
+5. **Validation**: Run `node scripts/find-missing-translations.js` to validate changes
+
+For comprehensive translation guidelines including language-specific rules, see `.kilocode/skills/translation/SKILL.md`.

+ 5 - 2
.vscode/launch.json

@@ -16,7 +16,8 @@
 			"preLaunchTask": "${defaultBuildTask}",
 			"env": {
 				"NODE_ENV": "development",
-				"VSCODE_DEBUG_MODE": "true"
+				"VSCODE_DEBUG_MODE": "true",
+				"KILOCODE_DEV_CLI_PATH": "${workspaceFolder}/cli/dist/index.js"
 			},
 			"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
 			"presentation": {
@@ -40,7 +41,8 @@
 			"preLaunchTask": "${defaultBuildTask}",
 			"env": {
 				"NODE_ENV": "development",
-				"VSCODE_DEBUG_MODE": "true"
+				"VSCODE_DEBUG_MODE": "true",
+				"KILOCODE_DEV_CLI_PATH": "${workspaceFolder}/cli/dist/index.js"
 			},
 			"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],
 			"presentation": { "hidden": false, "group": "tasks", "order": 1 }
@@ -57,6 +59,7 @@
 			"env": {
 				"NODE_ENV": "development",
 				"VSCODE_DEBUG_MODE": "true",
+				"KILOCODE_DEV_CLI_PATH": "${workspaceFolder}/cli/dist/index.js",
 				"KILOCODE_BACKEND_BASE_URL": "${input:kilocodeBackendBaseUrl}"
 			},
 			"resolveSourceMapLocations": ["${workspaceFolder}/**", "!**/node_modules/**"],

+ 24 - 1
.vscode/tasks.json

@@ -5,7 +5,7 @@
 	"tasks": [
 		{
 			"label": "watch",
-			"dependsOn": ["watch:pnpm", "watch:webview", "watch:bundle", "watch:tsc"],
+			"dependsOn": ["watch:pnpm", "watch:webview", "watch:bundle", "watch:tsc", "watch:cli"],
 			"presentation": {
 				"reveal": "never"
 			},
@@ -106,6 +106,29 @@
 				"reveal": "always"
 			}
 		},
+		{
+			"label": "watch:cli",
+			"dependsOn": ["watch:pnpm"],
+			"type": "shell",
+			"command": "pnpm --filter @kilocode/cli dev",
+			"group": "build",
+			"problemMatcher": {
+				"owner": "esbuild",
+				"pattern": {
+					"regexp": "^$"
+				},
+				"background": {
+					"activeOnStart": true,
+					"beginsPattern": "esbuild-problem-matcher#onStart",
+					"endsPattern": "esbuild-problem-matcher#onEnd"
+				}
+			},
+			"isBackground": true,
+			"presentation": {
+				"group": "watch",
+				"reveal": "always"
+			}
+		},
 		{
 			"label": "storybook",
 			"type": "shell",

+ 34 - 3
AGENTS.md

@@ -2,11 +2,39 @@
 
 Kilo Code is an open source AI coding agent for VS Code that generates code from natural language, automates tasks, and supports 500+ AI models.
 
-## Mode-Specific Rules
+## Project Structure
 
-For mode-specific guidance, see the following files:
+This is a pnpm monorepo using Turbo for task orchestration:
 
-- **Translate mode**: `.roo/rules-translate/AGENTS.md` - Translation and localization guidelines
+- **`src/`** - VSCode extension (core logic, API providers, tools)
+- **`webview-ui/`** - React frontend (chat UI, settings)
+- **`cli/`** - Standalone CLI package
+- **`packages/`** - Shared packages (`types`, `ipc`, `telemetry`, `cloud`)
+- **`jetbrains/`** - JetBrains plugin (Kotlin + Node.js host)
+- **`apps/`** - E2E tests, Storybook, docs
+
+Key source directories:
+
+- `src/api/providers/` - AI provider implementations (50+ providers)
+- `src/core/tools/` - Tool implementations (ReadFile, ApplyDiff, ExecuteCommand, etc.)
+- `src/services/` - Services (MCP, browser, checkpoints, code-index)
+
+## Build Commands
+
+```bash
+pnpm install          # Install all dependencies
+pnpm build            # Build extension (.vsix)
+pnpm lint             # Run ESLint
+pnpm check-types      # TypeScript type checking
+```
+
+## Skills
+
+- **Translation**: `.kilocode/skills/translation/SKILL.md` - Translation and localization guidelines
+
+## Workflows
+
+- **Add Missing Translations**: `.kilocode/workflows/add-missing-translations.md` - Run `/add-missing-translations` to find and fix missing translations
 
 ## Changesets
 
@@ -40,11 +68,13 @@ Kilo Code is a fork of [Roo Code](https://github.com/RooVetGit/Roo-Code). We per
 To minimize merge conflicts when syncing with upstream, mark Kilo Code-specific changes in shared code with `kilocode_change` comments.
 
 **Single line:**
+
 ```typescript
 const value = 42 // kilocode_change
 ```
 
 **Multi-line:**
+
 ```typescript
 // kilocode_change start
 const foo = 1
@@ -53,6 +83,7 @@ const bar = 2
 ```
 
 **New files:**
+
 ```typescript
 // kilocode_change - new file
 ```

+ 104 - 0
CHANGELOG.md

@@ -1,5 +1,109 @@
 # kilo-code
 
+## 4.144.0
+
+### Minor Changes
+
+- [#4888](https://github.com/Kilo-Org/kilocode/pull/4888) [`334328d`](https://github.com/Kilo-Org/kilocode/commit/334328de5fa1825726b07be5d587550de2c52d91) Thanks [@hassoncs](https://github.com/hassoncs)! - Show notifications when skills are added or removed from the project or global config
+
+### Patch Changes
+
+- [#4880](https://github.com/Kilo-Org/kilocode/pull/4880) [`909bca7`](https://github.com/Kilo-Org/kilocode/commit/909bca7665b91753c3a9fd0435b13f1c91bcb2f2) Thanks [@markijbema](https://github.com/markijbema)! - Fixed that some tasks in task history were red
+
+- [#4862](https://github.com/Kilo-Org/kilocode/pull/4862) [`10ce725`](https://github.com/Kilo-Org/kilocode/commit/10ce72547d207b4f03538ebb3dc525d5bd92727d) Thanks [@catrielmuller](https://github.com/catrielmuller)! - Add Kilo icon to editor toolbar for quick access to open Kilo from any context
+
+- [#4940](https://github.com/Kilo-Org/kilocode/pull/4940) [`9809864`](https://github.com/Kilo-Org/kilocode/commit/9809864ce51474c29b0db2635a19a92520a2f1f1) Thanks [@Drilmo](https://github.com/Drilmo)! - Add KILOCODE_DEV_CLI_PATH support for easier extension + CLI development workflow
+
+- [#4899](https://github.com/Kilo-Org/kilocode/pull/4899) [`7a58919`](https://github.com/Kilo-Org/kilocode/commit/7a58919c7e4e12e0c954031081e12745419bf8b9) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Disable ask_followup_question tool when yolo mode is enabled to prevent the agent from asking itself questions and auto-answering them. Applied to:
+
+    - XML tool descriptions (system prompt)
+    - Native tool filtering
+    - Tool execution (returns error message if model still tries to use the tool from conversation history)
+
+- [#4863](https://github.com/Kilo-Org/kilocode/pull/4863) [`c65b798`](https://github.com/Kilo-Org/kilocode/commit/c65b798d99cd07bae2312d284663cd298a1b3f9e) Thanks [@hassoncs](https://github.com/hassoncs)! - Allow users to pick an input device for Speech-to-Text input
+
+- [#4892](https://github.com/Kilo-Org/kilocode/pull/4892) [`b37c944`](https://github.com/Kilo-Org/kilocode/commit/b37c944a8bea644660b6f2c4400d0b47cbdee979) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix Agent Manager session disappearing immediately after starting due to gitUrl race condition
+
+- [#4898](https://github.com/Kilo-Org/kilocode/pull/4898) [`14b22b6`](https://github.com/Kilo-Org/kilocode/commit/14b22b6b9b947ceab6418d6e43962b5535adad1e) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix session becoming non-interactable after clicking "Finish to Branch" button. The session now remains active so users can continue working after committing changes.
+
+- [#4835](https://github.com/Kilo-Org/kilocode/pull/4835) [`d55c093`](https://github.com/Kilo-Org/kilocode/commit/d55c093797c4a816a86ee5ee000f32a98f28199b) Thanks [@lambertjosh](https://github.com/lambertjosh)! - Add section headers to model selection dropdowns for "Recommended models" and "All models"
+
+- [#4891](https://github.com/Kilo-Org/kilocode/pull/4891) [`20f1a16`](https://github.com/Kilo-Org/kilocode/commit/20f1a16e2ed37bd79332bac8ea1358b01c4acbc0) Thanks [@kevinvandijk](https://github.com/kevinvandijk)! - Fix: prevent double display of MCP marketplace section in settings view
+
+- [#4873](https://github.com/Kilo-Org/kilocode/pull/4873) [`72ed20b`](https://github.com/Kilo-Org/kilocode/commit/72ed20b686f28062fb795beb44377a993bb40a7b) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Improve support for VSCode's HTTP proxy settings
+
+- [#4901](https://github.com/Kilo-Org/kilocode/pull/4901) [`140bbf7`](https://github.com/Kilo-Org/kilocode/commit/140bbf7630a81591b18cc60a989690142e6b6039) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Agent Manager: Parallel mode no longer modifies .gitignore
+
+    Worktree exclusion rules are now written to `.git/info/exclude` instead, avoiding changes to tracked files in your repository.
+
+## 4.143.2
+
+### Patch Changes
+
+- [#4833](https://github.com/Kilo-Org/kilocode/pull/4833) [`2c7cd08`](https://github.com/Kilo-Org/kilocode/commit/2c7cd084bf4707eedda61fed554cf15fcc8b065b) Thanks [@sebastiand-cerebras](https://github.com/sebastiand-cerebras)! - Add `zai-glm-4.7` to Cerebras models
+
+- [#4853](https://github.com/Kilo-Org/kilocode/pull/4853) [`435c879`](https://github.com/Kilo-Org/kilocode/commit/435c879a29d55b75f5f6ffe7bf14854630e085cb) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Improved prompt caching when using Anthropic models on OpenRouter with native tool calling
+
+- [#4859](https://github.com/Kilo-Org/kilocode/pull/4859) [`35fb2ad`](https://github.com/Kilo-Org/kilocode/commit/35fb2adc65dfb1e71e28f7368f96765062c43579) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix Architect mode unnecessarily switching to Code mode to edit markdown files
+
+- [#4829](https://github.com/Kilo-Org/kilocode/pull/4829) [`4e09e36`](https://github.com/Kilo-Org/kilocode/commit/4e09e36bba165a2ab6f5e07f71a420faa49ea3ec) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix browser action results displaying raw base64 screenshot data as hexadecimal garbage
+
+## 4.143.1
+
+### Patch Changes
+
+- [#4832](https://github.com/Kilo-Org/kilocode/pull/4832) [`22a4ebf`](https://github.com/Kilo-Org/kilocode/commit/22a4ebfcd9f885b6ef9979dc6830226db9a4f397) Thanks [@Drilmo](https://github.com/Drilmo)! - Support Cmd+V for pasting images on macOS in VSCode terminal
+
+    - Detect empty bracketed paste (when clipboard contains image instead of text)
+    - Trigger clipboard image check on empty paste or paste timeout
+    - Add Cmd+V (meta key) support alongside Ctrl+V for image paste
+
+- [#3856](https://github.com/Kilo-Org/kilocode/pull/3856) [`91e0a17`](https://github.com/Kilo-Org/kilocode/commit/91e0a1788963b8be50c58881f11ded96516ab163) Thanks [@markijbema](https://github.com/markijbema)! - Faster autocomplete when using the Mistral provider
+
+- [#4839](https://github.com/Kilo-Org/kilocode/pull/4839) [`abaada6`](https://github.com/Kilo-Org/kilocode/commit/abaada6b7ced6d3f4e37e69441e722e453289b81) Thanks [@markijbema](https://github.com/markijbema)! - Enable autocomplete by default in the JetBrains extension
+
+- [#4831](https://github.com/Kilo-Org/kilocode/pull/4831) [`a9cbb2c`](https://github.com/Kilo-Org/kilocode/commit/a9cbb2cebd75e0c675dc3b55e7a1653ccb93921b) Thanks [@Drilmo](https://github.com/Drilmo)! - Fix paste truncation in VSCode terminal
+
+    - Prevent React StrictMode cleanup from interrupting paste operations
+    - Remove `completePaste()` and `clearBuffers()` from useEffect cleanup
+    - Paste buffer refs now persist across React re-mounts and flush properly when paste end marker is received
+
+- [#4847](https://github.com/Kilo-Org/kilocode/pull/4847) [`8ee812a`](https://github.com/Kilo-Org/kilocode/commit/8ee812a18da5da691bf76ee5c5d9d94cfb678f25) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Disable structured outputs for Anthropic models, because the tool schema doesn't yet support it
+
+- [#4843](https://github.com/Kilo-Org/kilocode/pull/4843) [`0e3520a`](https://github.com/Kilo-Org/kilocode/commit/0e3520a0aa9a74f7a28af1f820558d2343fd4fba) Thanks [@markijbema](https://github.com/markijbema)! - Filter unhelpful suggestions in chat autocomplete
+
+## 4.143.0
+
+### Minor Changes
+
+- [#4643](https://github.com/Kilo-Org/kilocode/pull/4643) [`bf89c48`](https://github.com/Kilo-Org/kilocode/commit/bf89c4849342d9c0f3cfa335d65e98980d869e36) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Migrate worktree creation from CLI to extension for parallel mode sessions
+
+### Patch Changes
+
+- [#4804](https://github.com/Kilo-Org/kilocode/pull/4804) [`e83c30a`](https://github.com/Kilo-Org/kilocode/commit/e83c30a4160309c45bcfedf60faad3eedff0549e) Thanks [@kiloconnect](https://github.com/apps/kiloconnect)! - Add comprehensive AGENTS.md documentation page to Agent Behavior section
+
+- [#4810](https://github.com/Kilo-Org/kilocode/pull/4810) [`2d8f5b4`](https://github.com/Kilo-Org/kilocode/commit/2d8f5b4f823750d22701d962ba27885b01f78acb) Thanks [@kiloconnect](https://github.com/apps/kiloconnect)! - Add `--append-system-prompt` CLI option to append custom instructions to the system prompt
+
+- [#4808](https://github.com/Kilo-Org/kilocode/pull/4808) [`3253a5f`](https://github.com/Kilo-Org/kilocode/commit/3253a5f0a9ef3db176b0cc027a9a0f246faa27e6) Thanks [@markijbema](https://github.com/markijbema)! - Rename and reorganize autocomplete settings to use more familiar terminology
+
+- [#4815](https://github.com/Kilo-Org/kilocode/pull/4815) [`1530050`](https://github.com/Kilo-Org/kilocode/commit/15300507c8febd2096282e97148e39a0bfda9e23) Thanks [@chrarnoldus](https://github.com/chrarnoldus)! - Allow null for tool arguments
+
+## 4.142.0
+
+### Minor Changes
+
+- [#4587](https://github.com/Kilo-Org/kilocode/pull/4587) [`d1c35c5`](https://github.com/Kilo-Org/kilocode/commit/d1c35c54c253b22a264ee4ce90fd25f5d93343da) Thanks [@hassoncs](https://github.com/hassoncs)! - Improve the initial setup experience for the speech-to-text feature by adding an inline setup tooltip
+
+### Patch Changes
+
+- [#4785](https://github.com/Kilo-Org/kilocode/pull/4785) [`acc529e`](https://github.com/Kilo-Org/kilocode/commit/acc529e884be601d635ad9e714a0f3b2a4e9b639) Thanks [@markijbema](https://github.com/markijbema)! - Removed the cmd-i (quick inline task) functionality, as cmd-k-a (add to context) is now equivalent
+
+- [#4765](https://github.com/Kilo-Org/kilocode/pull/4765) [`725b0bc`](https://github.com/Kilo-Org/kilocode/commit/725b0bc56d1262b9e847861db86a3609c40479d9) Thanks [@Drilmo](https://github.com/Drilmo)! - Fixed exit prompt showing "Cmd+C" instead of "Ctrl+C" on Mac. Ctrl+C is the universal terminal interrupt signal on all platforms.
+
+- [#4787](https://github.com/Kilo-Org/kilocode/pull/4787) [`84033fa`](https://github.com/Kilo-Org/kilocode/commit/84033fa3015a757b358cc4799308b8209646ec5e) Thanks [@markijbema](https://github.com/markijbema)! - Keep config screen in sync with whether chat autocomplete is enabled
+
+- [#4800](https://github.com/Kilo-Org/kilocode/pull/4800) [`c089dc2`](https://github.com/Kilo-Org/kilocode/commit/c089dc2351daefe7690adf1a3f01cc8b82a27409) Thanks [@hassoncs](https://github.com/hassoncs)! - Add fuzzy matching to / commands
+
 ## 4.141.2
 
 ### Patch Changes

+ 2 - 0
README.md

@@ -15,6 +15,7 @@
 - ✅ Checks its own work
 - 🧪 Run terminal commands
 - 🌐 Automate the browser
+- ⚡ Inline autocomplete suggestions
 - 🤖 Latest AI models
 - 🎁 API keys optional
 - 💡 **Get $20 in bonus credits when you top-up for the first time** Credits can be used with 500+ models like Gemini 3 Pro, Claude 4.5 Sonnet & Opus, and GPT-5
@@ -29,6 +30,7 @@
 ## Key Features
 
 - **Code Generation:** Kilo can generate code using natural language.
+- **Inline Autocomplete:** Get intelligent code completions as you type, powered by AI.
 - **Task Automation:** Kilo can automate repetitive coding tasks.
 - **Automated Refactoring:** Kilo can refactor and improve existing code.
 - **MCP Server Marketplace**: Kilo can easily find, and use MCP servers to extend the agent capabilities.

+ 75 - 15
apps/kilocode-docs/docs/advanced-usage/agent-manager.md

@@ -13,6 +13,7 @@ This page reflects the actual implementation in the extension.
 
 - Install/update the Kilo Code CLI (latest) — see [CLI setup](/cli)
 - Open a project in VS Code (workspace required)
+- Authentication: You must be logged in via the extension settings OR use CLI with kilocode as provider (see [Authentication Requirements](#authentication-requirements))
 
 ## Opening the Agent Manager
 
@@ -42,19 +43,74 @@ You can continue a session later (local or remote):
 
 Parallel Mode runs the agent in an isolated Git worktree branch, keeping your main branch clean.
 
-- Enable the “Parallel Mode” toggle before starting
+- Enable the "Parallel Mode" toggle before starting
 - The extension prevents using Parallel Mode inside an existing worktree
     - Open the main repository (where .git is a directory) to use this feature
-- While running, the Agent Manager parses and surfaces:
-    - Branch name created/used
-    - Worktree path
-    - A completion/merge instruction message when the agent finishes
-- After completion
-    - Review the branch in your VCS UI
-    - Merge or cherry-pick the changes as desired
-    - Clean up the worktree when finished
 
-If you need to resume with Parallel Mode later, the extension re-attaches to the same session with the same branch context.
+### Worktree Location
+
+Worktrees are created in `.kilocode/worktrees/` within your project directory. This folder is automatically excluded from git via `.git/info/exclude` (a local-only ignore file that doesn't require a commit).
+
+```
+your-project/
+├── .git/
+│   └── info/
+│       └── exclude   # local ignore rules (includes .kilocode/worktrees/)
+├── .kilocode/
+│   └── worktrees/
+│       └── feature-branch-1234567890/   # isolated working directory
+└── ...
+```
+
+### While Running
+
+The Agent Manager surfaces:
+
+- Branch name created/used
+- Worktree path
+- A completion/merge instruction message when the agent finishes
+
+### After Completion
+
+- The worktree is cleaned up automatically, but the branch is preserved
+- Review the branch in your VCS UI
+- Merge or cherry-pick the changes as desired
+
+### Resuming Sessions
+
+If you resume a Parallel Mode session later, the extension will:
+
+1. Reuse the existing worktree if it still exists
+2. Or recreate it from the session's branch
+
+## Authentication Requirements
+
+The Agent Manager requires proper authentication for full functionality, including session syncing and cloud features.
+
+### Supported Authentication Methods
+
+1. **Kilo Code Extension (Recommended)**
+
+    - Sign in through the extension settings
+    - Provides seamless authentication for the Agent Manager
+    - Enables session syncing and cloud features
+
+2. **CLI with Kilo Code Provider**
+    - Use the CLI configured with `kilocode` as the provider
+    - Run `kilocode config` to set up authentication
+    - See [CLI setup](/cli) for details
+
+### BYOK Limitations
+
+**Important:** Bring Your Own Key (BYOK) is not yet supported with the Agent Manager.
+
+If you're using BYOK with providers like Anthropic, OpenAI, or OpenRouter:
+
+- The Agent Manager will not have access to cloud-synced sessions
+- Session syncing features will be unavailable
+- You must use one of the supported authentication methods above for full functionality
+
+To use the Agent Manager with all features enabled, switch to the Kilo Code provider or sign in through the extension.
 
 ## Remote sessions (Cloud)
 
@@ -66,19 +122,23 @@ When signed in (Kilo Cloud), the Agent Manager lists your recent cloud-synced se
 - Selecting a remote session loads its message transcript
 - To continue the work locally, send a message — the Agent Manager will spawn a local process bound to that session
 
-Message transcripts are fetched from a signed blob and exclude internal checkpoint “save” markers as chat rows (checkpoints still appear as dedicated entries in the UI).
+Message transcripts are fetched from a signed blob and exclude internal checkpoint "save" markers as chat rows (checkpoints still appear as dedicated entries in the UI).
 
 ## Troubleshooting
 
 - CLI not found or outdated
     - Install/update the CLI: [CLI setup](/cli)
-    - If you see an “unknown option --json-io” error, update to the latest CLI
-- “Please open a folder…” error
+    - If you see an "unknown option --json-io" error, update to the latest CLI
+- "Please open a folder…" error
     - The Agent Manager requires a VS Code workspace folder
-- “Cannot use parallel mode from within a git worktree”
+- "Cannot use parallel mode from within a git worktree"
     - Open the main repository (where .git is a directory), not a worktree checkout
 - Remote sessions not visible
-    - Ensure you’re signed in and the repo’s remote URL matches the sessions you expect to see
+    - Ensure you're signed in and the repo's remote URL matches the sessions you expect to see
+    - If using BYOK, session syncing is not available — switch to Kilo Code provider or sign in through the extension
+- Authentication errors
+    - Verify you're logged in via extension settings or using CLI with kilocode provider
+    - BYOK configurations do not support Agent Manager authentication
 
 ## Related features
 

+ 1 - 1
apps/kilocode-docs/docs/advanced-usage/auto-cleanup.md

@@ -241,7 +241,7 @@ Task data is stored in your VS Code global storage location:
 ## Related Features
 
 - [**Checkpoints**](../features/checkpoints): Version control for tasks that can be restored
-- [**Settings Management**](../features/settings-management): Export/import settings including cleanup configuration
+- [**Settings Management**](../basic-usage/settings-management): Export/import settings including cleanup configuration
 - [**Task History**](../basic-usage/the-chat-interface): Managing and organizing your task history
 
 ## Frequently Asked Questions

+ 0 - 1
apps/kilocode-docs/docs/advanced-usage/code-reviews.md

@@ -159,5 +159,4 @@ The Review Agent is ideal for:
 - The agent reviews **only the changed files**, not the entire repository.
 - Some highly dynamic or domain-specific code may require additional context in custom instructions.
 - The agent will only run on **selected repositories**.
-- **PRs from forks are not supported**. Only pull requests from branches within the same repository can be automatically reviewed.
 - During beta, review capacity may be throttled for extremely large PRs.

+ 1 - 1
apps/kilocode-docs/docs/advanced-usage/memory-bank.md

@@ -35,7 +35,7 @@ When Memory Bank is active, Kilo Code begins each task with `[Memory Bank: Activ
 
 ## How Memory Bank Works
 
-Memory Bank is built on Kilo Code's [Custom Rules](/advanced-usage/custom-rules) feature, providing a specialized framework for project documentation. Memory Bank files are standard markdown files stored in `.kilocode/rules/memory-bank` folder within your project repository. They're not hidden or proprietary - they're regular documentation files that both you and Kilo Code can access.
+Memory Bank is built on Kilo Code's [Custom Rules](/agent-behavior/custom-rules) feature, providing a specialized framework for project documentation. Memory Bank files are standard markdown files stored in `.kilocode/rules/memory-bank` folder within your project repository. They're not hidden or proprietary - they're regular documentation files that both you and Kilo Code can access.
 
 At the start of every task, Kilo Code reads all Memory Bank files to build a comprehensive understanding of your project. This happens automatically without requiring any action from you. Kilo Code then indicates successful Memory Bank activation with `[Memory Bank: Active]` at the beginning of its response, followed by a brief summary of its understanding of your project.
 

+ 3 - 3
apps/kilocode-docs/docs/advanced-usage/migrating-from-cursor-windsurf.md

@@ -397,9 +397,9 @@ mkdir -p .kilocode/rules-docs
 
 ## Next Steps
 
-- [Learn about Custom Rules](/advanced-usage/custom-rules)
-- [Explore Custom Modes](/features/custom-modes)
-- [Set up Custom Instructions](/advanced-usage/custom-instructions)
+- [Learn about Custom Rules](/agent-behavior/custom-rules)
+- [Explore Custom Modes](/agent-behavior/custom-modes)
+- [Set up Custom Instructions](/agent-behavior/custom-instructions)
 - [Join our Discord](https://kilo.ai/discord) for migration support
 
 ## Additional Resources

+ 154 - 0
apps/kilocode-docs/docs/agent-behavior/agents-md.md

@@ -0,0 +1,154 @@
+# AGENTS.md Files
+
+AGENTS.md files provide a standardized way to configure AI agent behavior across different AI coding tools. They allow you to define project-specific instructions, coding standards, and guidelines that AI agents should follow when working with your codebase.
+
+## What is AGENTS.md?
+
+AGENTS.md is an open standard for configuring AI agent behavior in software projects. It's a simple Markdown file placed at the root of your project that contains instructions for AI coding assistants. The standard is supported by multiple AI coding tools, including Kilo Code, Cursor, and Windsurf.
+
+Think of AGENTS.md as a "README for AI agents" - it tells the AI how to work with your specific project, what conventions to follow, and what constraints to respect.
+
+## Why Use AGENTS.md?
+
+- **Portability**: Works across multiple AI coding tools without modification
+- **Version Control**: Lives in your repository alongside your code
+- **Team Consistency**: Ensures all team members' AI assistants follow the same guidelines
+- **Project-Specific**: Tailored to your project's unique requirements and conventions
+- **Simple Format**: Plain Markdown - no special syntax or configuration required
+
+## File Location and Naming
+
+### Project-Level AGENTS.md
+
+Place your AGENTS.md file at the **root of your project**:
+
+```
+my-project/
+├── AGENTS.md          # Primary filename (recommended)
+├── src/
+├── package.json
+└── README.md
+```
+
+**Supported filenames** (in order of precedence):
+
+1. `AGENTS.md` (uppercase, plural - recommended)
+2. `AGENT.md` (uppercase, singular - fallback)
+
+:::warning Case Sensitivity
+The filename must be uppercase (`AGENTS.md`), not lowercase (`agents.md`). This ensures consistency across different operating systems and tools.
+:::
+
+### Subdirectory AGENTS.md Files
+
+You can also place AGENTS.md files in subdirectories to provide context-specific instructions:
+
+```
+my-project/
+├── AGENTS.md                    # Root-level instructions
+├── src/
+│   └── backend/
+│       └── AGENTS.md            # Backend-specific instructions
+└── docs/
+    └── AGENTS.md                # Documentation-specific instructions
+```
+
+When working in a subdirectory, Kilo Code will load both the root AGENTS.md and any subdirectory AGENTS.md files, with subdirectory files taking precedence for conflicting instructions.
+
+## File Protection
+
+Both `AGENTS.md` and `AGENT.md` are **write-protected files** in Kilo Code. This means:
+
+- The AI agent cannot modify these files without explicit user approval
+- You'll be prompted to confirm any changes to these files
+- This prevents accidental modifications to your project's AI configuration
+
+## Basic Syntax and Structure
+
+AGENTS.md files use standard Markdown syntax. There's no required structure, but organizing your content with headers and lists makes it easier for AI models to parse and understand.
+
+### Recommended Structure
+
+```markdown
+# Project Name
+
+Brief description of the project and its purpose.
+
+## Code Style
+
+- Use TypeScript for all new files
+- Follow ESLint configuration
+- Use 2 spaces for indentation
+
+## Architecture
+
+- Follow MVC pattern
+- Keep components under 200 lines
+- Use dependency injection
+
+## Testing
+
+- Write unit tests for all business logic
+- Maintain >80% code coverage
+- Use Jest for testing
+
+## Security
+
+- Never commit API keys or secrets
+- Validate all user inputs
+- Use parameterized queries for database access
+```
+
+## Best Practices
+
+- **Be specific and clear** - Use concrete rules like "limit cyclomatic complexity to < 10" instead of vague guidance like "write good code"
+- **Include code examples** - Show patterns for error handling, naming conventions, or architecture decisions
+- **Organize by category** - Group related guidelines under clear headers (Code Style, Architecture, Testing, Security)
+- **Keep it concise** - Use bullet points and direct language; avoid long paragraphs
+- **Update regularly** - Review and revise as your project's conventions evolve
+
+## How AGENTS.md Works in Kilo Code
+
+### Loading Behavior
+
+When you start a task in Kilo Code:
+
+1. Kilo Code checks for `AGENTS.md` or `AGENT.md` at the project root
+2. If found, the content is loaded and included in the AI's context
+3. The AI follows these instructions throughout the conversation
+4. Changes to AGENTS.md take effect in new tasks (reload may be required)
+
+### Interaction with Other Rules
+
+AGENTS.md works alongside Kilo Code's other configuration systems:
+
+| Feature                                                        | Scope   | Location                  | Purpose                                    | Priority    |
+| -------------------------------------------------------------- | ------- | ------------------------- | ------------------------------------------ | ----------- |
+| **[Mode-specific Custom Rules](/agent-behavior/custom-rules)** | Project | `.kilocode/rules-{mode}/` | Mode-specific rules and constraints        | 1 (Highest) |
+| **[Custom Rules](/agent-behavior/custom-rules)**               | Project | `.kilocode/rules/`        | Kilo Code-specific rules and constraints   | 2           |
+| **AGENTS.md**                                                  | Project | Project root or subfolder | Cross-tool standard for project guidelines | 3           |
+| **[Global Custom Rules](/agent-behavior/custom-rules)**        | Global  | `~/.kilocode/rules/`      | Global Kilo Code rules                     | 4           |
+| **[Custom Instructions](/agent-behavior/custom-instructions)** | Global  | IDE settings              | Personal preferences across all projects   | 5 (Lowest)  |
+
+### Enabling/Disabling AGENTS.md
+
+AGENTS.md support is **enabled by default** in Kilo Code. To disable it, edit `settings.json`:
+
+```json
+{
+	"kilocode.useAgentRules": false
+}
+```
+
+## Related Features
+
+- **[Custom Rules](/agent-behavior/custom-rules)** - Kilo Code-specific rules with more control
+- **[Custom Modes](/agent-behavior/custom-modes)** - Specialized workflows with specific permissions
+- **[Custom Instructions](/agent-behavior/custom-instructions)** - Personal preferences across all projects
+- **[Migrating from Cursor or Windsurf](/advanced-usage/migrating-from-cursor-windsurf)** - Migration guide for other tools
+
+## External Resources
+
+- [AGENTS.md Specification](https://agents.md) - Official standard documentation
+- [dotagent](https://github.com/johnlindquist/dotagent) - Universal converter tool for agent configuration files
+- [awesome-cursorrules](https://github.com/PatrickJS/awesome-cursorrules) - 700+ example rules you can adapt

+ 5 - 5
apps/kilocode-docs/docs/advanced-usage/custom-instructions.md → apps/kilocode-docs/docs/agent-behavior/custom-instructions.md

@@ -7,7 +7,7 @@ Custom Instructions allow you to personalize how Kilo Code behaves, providing sp
 Custom Instructions define specific Extension behaviors, preferences, and constraints beyond Kilo's basic role definition. Examples include coding style, documentation standards, testing requirements, and workflow guidelines.
 
 :::info Custom Instructions vs Rules
-Custom Instructions are IDE-wide and are applied across all workspaces and maintain your preferences regardless of which project you're working on. Unlike Instructions, [Custom Rules](/advanced-usage/custom-rules.md) are project specific and allow you to setup workspace-based ruleset.
+Custom Instructions are IDE-wide and are applied across all workspaces and maintain your preferences regardless of which project you're working on. Unlike Instructions, [Custom Rules](/agent-behavior/custom-rules) are project specific and allow you to setup workspace-based ruleset.
 :::
 
 ## Setting Custom Instructions
@@ -36,7 +36,7 @@ Mode-specific instructions can be set using the Modes Tab
 
 ## Related Features
 
-- [Custom Modes](/docs/features/custom-modes)
-- [Custom Rules](/advanced-usage/custom-rules)
-- [Settings Management](/docs/features/settings-management)
-- [Auto-Approval Settings](/docs/features/auto-approving-actions)
+- [Custom Modes](/agent-behavior/custom-modes)
+- [Custom Rules](/agent-behavior/custom-rules)
+- [Settings Management](/basic-usage/settings-management)
+- [Auto-Approval Settings](/features/auto-approving-actions)

+ 0 - 0
apps/kilocode-docs/docs/features/custom-modes.md → apps/kilocode-docs/docs/agent-behavior/custom-modes.md


+ 4 - 4
apps/kilocode-docs/docs/advanced-usage/custom-rules.md → apps/kilocode-docs/docs/agent-behavior/custom-rules.md

@@ -217,7 +217,7 @@ If your custom rules aren't being properly followed:
 
 ## Related Features
 
-- [Custom Modes](/docs/features/custom-modes)
-- [Custom Instructions](/advanced-usage/custom-instructions)
-- [Settings Management](/docs/features/settings-management)
-- [Auto-Approval Settings](/docs/features/auto-approving-actions)
+- [Custom Modes](/agent-behavior/custom-modes)
+- [Custom Instructions](/agent-behavior/custom-instructions)
+- [Settings Management](/basic-usage/settings-management)
+- [Auto-Approval Settings](/features/auto-approving-actions)

+ 1 - 1
apps/kilocode-docs/docs/advanced-usage/prompt-engineering.md → apps/kilocode-docs/docs/agent-behavior/prompt-engineering.md

@@ -44,7 +44,7 @@ Custom instructions are added to the system prompt, providing persistent guidanc
 - Define project-specific conventions.
 - Adjust Kilo Code's tone or personality.
 
-See the [Custom Instructions](/advanced-usage/custom-instructions) section for more details.
+See the [Custom Instructions](/agent-behavior/custom-instructions) section for more details.
 
 ## Handling Ambiguity
 

+ 57 - 59
apps/kilocode-docs/docs/features/skills.md → apps/kilocode-docs/docs/agent-behavior/skills.md

@@ -66,6 +66,48 @@ your-project/
             └── SKILL.md
 ```
 
+## Mode-Specific Skills
+
+To create a skill that only appears in a specific mode:
+
+```bash
+# For Code mode only
+mkdir -p ~/.kilocode/skills-code/typescript-patterns
+
+# For Architect mode only
+mkdir -p ~/.kilocode/skills-architect/microservices
+```
+
+The directory naming pattern is `skills-{mode-slug}` where `{mode-slug}` matches the mode's identifier (e.g., `code`, `architect`, `ask`, `debug`).
+
+## Priority and Overrides
+
+When multiple skills share the same name, Kilo Code uses these priority rules:
+
+1. **Project skills override global skills** - A project skill with the same name takes precedence
+2. **Mode-specific skills override generic skills** - A skill in `skills-code/` overrides the same skill in `skills/` when in Code mode
+
+This allows you to:
+
+- Define global skills for personal use
+- Override them per-project when needed
+- Customize behavior for specific modes
+
+## When Skills Are Loaded
+
+Skills are discovered when Kilo Code initializes:
+
+- When VSCode starts
+- When you reload the VSCode window (`Cmd+Shift+P` → "Developer: Reload Window")
+
+Skills directories are monitored for changes to `SKILL.md` files. However, the most reliable way to pick up new skills is to reload VS or the Kilo Code extension.
+
+**Adding or modifying skills requires reloading VSCode for changes to take effect.**
+
+## Using Symlinks
+
+You can symlink skills directories to share skills across machines or from a central repository. When using symlinks, the skill's `name` field must match the **symlink name**, not the target directory name.
+
 ## SKILL.md Format
 
 The `SKILL.md` file uses YAML frontmatter followed by Markdown content containing the instructions:
@@ -153,30 +195,6 @@ my-skill/
 
 These additional files can be referenced from your skill's instructions, allowing the agent to read documentation, execute scripts, or use templates as needed.
 
-## Priority and Overrides
-
-When multiple skills share the same name, Kilo Code uses these priority rules:
-
-1. **Project skills override global skills** - A project skill with the same name takes precedence
-2. **Mode-specific skills override generic skills** - A skill in `skills-code/` overrides the same skill in `skills/` when in Code mode
-
-This allows you to:
-
-- Define global skills for personal use
-- Override them per-project when needed
-- Customize behavior for specific modes
-
-## When Skills Are Loaded
-
-Skills are discovered when Kilo Code initializes:
-
-- When VSCode starts
-- When you reload the VSCode window (`Cmd+Shift+P` → "Developer: Reload Window")
-
-Skills directories are monitored for changes to `SKILL.md` files. However, the most reliable way to pick up new skills is to reload VS or the Kilo Code extension.
-
-**Adding or modifying skills requires reloading VSCode for changes to take effect.**
-
 ## Example: Creating a Skill
 
 1. Create the skill directory:
@@ -224,34 +242,6 @@ Skills directories are monitored for changes to `SKILL.md` files. However, the m
 
 4. The skill will now be available in all modes
 
-## Mode-Specific Skills
-
-To create a skill that only appears in a specific mode:
-
-```bash
-# For Code mode only
-mkdir -p ~/.kilocode/skills-code/typescript-patterns
-
-# For Architect mode only
-mkdir -p ~/.kilocode/skills-architect/microservices
-```
-
-The directory naming pattern is `skills-{mode-slug}` where `{mode-slug}` matches the mode's identifier (e.g., `code`, `architect`, `ask`, `debug`).
-
-## Using Symlinks
-
-You can symlink skills directories to share skills across machines or from a central repository:
-
-```bash
-# Symlink entire skills directory
-ln -s /path/to/shared/skills ~/.kilocode/skills
-
-# Or symlink individual skills
-ln -s /path/to/shared/api-design ~/.kilocode/skills/api-design
-```
-
-When using symlinks, the skill's `name` field must match the **symlink name**, not the target directory name.
-
 ## Finding Skills
 
 There are community efforts to build and share agent skills. Some resources include:
@@ -259,10 +249,6 @@ There are community efforts to build and share agent skills. Some resources incl
 - [Skills Marketplace](https://skillsmp.com/) - Community marketplace of skills
 - [Skill Specification](https://agentskills.io/home) - Agent Skills specification
 
-### Creating Your Own
-
-Skills are simple Markdown files with frontmatter. Start with your existing prompt templates or instructions and convert them to the skill format.
-
 ## Troubleshooting
 
 ### Skill Not Loading?
@@ -275,6 +261,18 @@ Skills are simple Markdown files with frontmatter. Start with your existing prom
 
 4. **Check file location**: Ensure `SKILL.md` is directly inside the skill directory, not nested further.
 
+### Verifying a Skill is Activated
+
+To confirm a skill is properly loaded and available to the agent, you can ask the agent directly. Simply send a message like:
+
+- "Do you have access to skill X?"
+- "Is the skill called X loaded?"
+- "What skills do you have available?"
+
+The agent will respond with information about whether the skill is loaded and accessible. This is the most reliable way to verify that a skill has been activated after adding it or reloading VSCode.
+
+If the agent confirms the skill is available, you're ready to use it. If not, check the troubleshooting steps above to identify and resolve the issue.
+
 ### Common Errors
 
 | Error                           | Cause                                        | Solution                                         |
@@ -285,6 +283,6 @@ Skills are simple Markdown files with frontmatter. Start with your existing prom
 
 ## Related
 
-- [Custom Modes](custom-modes) - Create custom modes that can use specific skills
-- [Custom Instructions](../advanced-usage/custom-instructions) - Global instructions vs. skill-based instructions
-- [Custom Rules](../advanced-usage/custom-rules) - Project-level rules complementing skills
+- [Custom Modes](/agent-behavior/custom-modes) - Create custom modes that can use specific skills
+- [Custom Instructions](/agent-behavior/custom-instructions) - Global instructions vs. skill-based instructions
+- [Custom Rules](/agent-behavior/custom-rules) - Project-level rules complementing skills

+ 0 - 0
apps/kilocode-docs/docs/features/slash-commands/workflows.mdx → apps/kilocode-docs/docs/agent-behavior/workflows.mdx


+ 22 - 20
apps/kilocode-docs/docs/basic-usage/autocomplete.md

@@ -16,8 +16,6 @@ Autocomplete analyzes your code context and provides:
 - **Contextual suggestions** based on your surrounding code
 - **Multi-line completions** for complex code structures
 
-The feature uses your selected AI provider to generate intelligent suggestions that match your coding style and project context.
-
 ## Triggering Options
 
 ### Pause to Complete
@@ -28,24 +26,6 @@ When enabled, Kilo Code automatically triggers autocomplete when you pause typin
 - Default is 3 seconds, but this can be adjusted up or down
 - Shorter delays mean quicker suggestions but may be more resource-intensive
 
-### Quick Task (Cmd+I)
-
-Need to make a quick change? The Quick Task feature allows you to:
-
-1. Select code in your editor (or place your cursor where you want changes)
-2. Press `Cmd+I` (Mac) or `Ctrl+I` (Windows/Linux)
-3. Describe your goal in plain English
-4. Receive a code suggestion without going to the chat
-
-**Examples:**
-
-- "create a React component with these props"
-- "add error handling to this function"
-- "convert this to TypeScript"
-- "optimize this loop for performance"
-
-You can customize the keyboard shortcut in VS Code's keyboard shortcuts settings.
-
 ### Manual Autocomplete (Cmd+L)
 
 For more control over when suggestions appear:
@@ -64,6 +44,28 @@ This is ideal for:
 
 You can customize this keyboard shortcut as well in your VS Code settings.
 
+## Provider and Model Selection
+
+Autocomplete currently uses **Codestral** (by Mistral AI) as the underlying model. This model is specifically optimized for code completion tasks and provides fast, high-quality suggestions.
+
+### How the Provider is Chosen
+
+Kilo Code automatically selects a provider for autocomplete in the following priority order:
+
+- **Mistral** (using `codestral-latest`)
+- **Kilo Code** (using `mistralai/codestral-2508`)
+- **OpenRouter** (using `mistralai/codestral-2508`)
+- **Requesty** (using `mistral/codestral-latest`)
+- **Bedrock** (using `mistral.codestral-2508-v1:0`)
+- **Hugging Face** (using `mistralai/Codestral-22B-v0.1`)
+- **LiteLLM** (using `codestral/codestral-latest`)
+- **LM Studio** (using `mistralai/codestral-22b-v0.1`)
+- **Ollama** (using `codestral:latest`)
+
+:::note
+**Model Selection is Currently Fixed**: At this time, you cannot freely choose a different model for autocomplete. The feature is designed to work specifically with Codestral, which is optimized for Fill-in-the-Middle (FIM) completions. Support for additional models may be added in future releases.
+:::
+
 ## Disable Rival Autocomplete
 
 We recommend disabling rival autocompletes to optimize your experience with Kilo Code. To disable GitHub Copilot autocomplete in VSCode, go to **Settings** and navigate to **GitHub** > **Copilot: Advanced** (or search for 'copilot').

+ 1 - 1
apps/kilocode-docs/docs/basic-usage/git-commit-generation.md

@@ -154,4 +154,4 @@ The feature integrates with VS Code's built-in git functionality. If you encount
 ## Related Features
 
 - [API Configuration Profiles](/features/api-configuration-profiles) - Use different models for commit generation
-- [Settings Management](/features/settings-management) - Manage all your Kilo Code preferences
+- [Settings Management](/basic-usage/settings-management) - Manage all your Kilo Code preferences

+ 0 - 0
apps/kilocode-docs/docs/features/settings-management.md → apps/kilocode-docs/docs/basic-usage/settings-management.md


+ 1 - 1
apps/kilocode-docs/docs/basic-usage/using-modes.md

@@ -87,4 +87,4 @@ Four ways to switch modes:
 
 ## Custom Modes
 
-Create your own specialized assistants by defining tool access, file permissions, and behavior instructions. Custom modes help enforce team standards or create purpose-specific assistants. See [Custom Modes documentation](/features/custom-modes) for setup instructions.
+Create your own specialized assistants by defining tool access, file permissions, and behavior instructions. Custom modes help enforce team standards or create purpose-specific assistants. See [Custom Modes documentation](/agent-behavior/custom-modes) for setup instructions.

+ 67 - 0
apps/kilocode-docs/docs/contributing/architecture/annual-billing.md

@@ -0,0 +1,67 @@
+---
+sidebar_position: 3
+title: "Annual Billing"
+---
+
+# Annual Billing
+
+# Overview
+
+we want to switch to doing annual billing for teams and enterprise with a 1 month free and a "self-serve" sign up.
+
+# Requirements
+
+- no more 20$ of one time free credits on team signup per seat. **this is done**
+- enable 30 day trial for both teams and enterprise
+    - no credit card required
+    - self-serve enterprise comes with no self-serve SSO. There's a button that puts them in touch with sales. (it costs us 125 a month for SSO per org)
+- monthly plan is not accessible via the UI but is still in effect for existing customers and can be flagged back on easily.
+- trial users can only upgrade to annual plans, 348/teams seat or $3588/ent seat, but we always talk about pricing in monthly terms.
+- once trial expires, the organization will be denied access to the openrouter proxy endpoint, effectively disabling their kilocode usage w/ our API provider, and any existing outstanding credits they purchased will be locked up until they subscribe.
+
+### Non-requirements
+
+- fully self-service SSO enrollment for enterprise. There's still a bit of a touch required. Its possible to implement, but out of scope for this spec.
+- pro-rated cancellation or refunds handled in a self-serve way.
+- elastic seat counts with custom billing agreements for enterprise organizations.
+- a full redesign of the team/enterprise sign up and pre-creation / marketing flow.
+
+# System Design
+
+System design is pretty straight-forward as we can _mostly_ leverage existing infrastructure and code.
+
+- System remains the same other than adding a `billing_cycle` column to `organization_seats_purcahses` where we can track if it is `monthly` or `yearly`. The migration will set the default to `monthly` so we backfill all existing customers.
+- We will use `created_at` on the organization as the start date for the free trial. If the organization does not have a valid entry in `organization_seats_purchases` after 30 days, we will disable their access to the openrouter proxy endpoint.
+
+## Engineering Scope
+
+#### Migrations:
+
+- add `billing_cycle TEXT NOT NULL DEFAULT 'monthly'` to `organization_seats_purchases`.
+- add `plan TEXT NOT NULL DEFAULT 'teams'` to `organizations` table which can be `teams` or `enterprise`. (While not strictly required we shouldn't rely on `seats_required` to decide if an org is a team or enterprise account and now is a good opportunity to fix this. Manually go through and set the very small number of design partner orgs and our org into `enterprise.` for now.)
+
+#### Tasks:
+
+- create yearly billing subscription product for teams AND for enterprise in stripe.
+- change the organization create flow to create organization on submit (it does this now) but instead of redirecting to stripe to pay, redirect to organization page. Do not require an ahead-of-time seat count on either teams or enterprise.
+- update logic for checking & displaying seats to take into consideration the free trial period, and allow invites for an unlimited number of seats while the trial is active.
+- update subscription management page to allow for creating a new subscription from the page.
+- update logic to actually block organizations which are not active on seats (they are either over their paid seat count or do not have an active seats purchases subscription). [a ticket for this already exists](https://github.com/orgs/Kilo-Org/projects/11?pane=issue&itemId=126001076&issue=Kilo-Org%7Ckilocode-backend%7C2167) note: this can wait until the end as by definition no one can have their trial expire for at least 30 days so we have a 30 day buffer to implement this.
+
+### Marketing Scope
+
+As a fast follow or in parallel the seats pod will pair up with someone from marketing or devrel to work on our engagement with this feature.
+
+- update / redesign team/enterprise "create" page in app with better CTAs
+- work with eng to get the 'buy credits' action more importantly called out when a new org is created. General org onboarding flow (both teams and enterprise) needs help.
+- significantly improve call-to-action flows around upgrading to paid subscriptions with potentially progressively louder noise as we get closer to the end of trial notice.
+- send welcome email when org is created explaining the trail period.
+- probably cut new videos to show off the enterprise features
+
+# Compliance Considerations
+
+No compliance concerns.
+
+# Features for the future
+
+Talks about what we might want to build or improve upon in the future but is out-of-scope of this spec.

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-enterprise-mcp-controls.md → apps/kilocode-docs/docs/contributing/architecture/enterprise-mcp-controls.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 4
-title: "Spec: Enterprise MCP Controls"
+title: "Enterprise MCP Controls"
 ---
 
-# Spec: Enterprise MCP Controls
+# Enterprise MCP Controls
 
 ### Overview
 

+ 1 - 1
apps/kilocode-docs/docs/contributing/specs/spec-template.md → apps/kilocode-docs/docs/contributing/architecture/feature-template.md

@@ -3,7 +3,7 @@ sidebar_position: 2
 title: "Spec Template"
 ---
 
-# SPEC: Template
+# Template
 
 # Overview
 

+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/enterprise-mcp-controls-org-user-install.png → apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-org-user-install.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/enterprise-mcp-controls-today.png → apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-today.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/enterprise-mcp-controls-with-ent-control.png → apps/kilocode-docs/docs/contributing/architecture/img/enterprise-mcp-controls-with-ent-control.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/organization-modes-library-1.png → apps/kilocode-docs/docs/contributing/architecture/img/organization-modes-library-1.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/organization-modes-library-2.png → apps/kilocode-docs/docs/contributing/architecture/img/organization-modes-library-2.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/track-repo-url-system-design.png → apps/kilocode-docs/docs/contributing/architecture/img/track-repo-url-system-design.png


+ 0 - 0
apps/kilocode-docs/docs/contributing/specs/img/voice-transcription-architecture.png → apps/kilocode-docs/docs/contributing/architecture/img/voice-transcription-architecture.png


+ 25 - 60
apps/kilocode-docs/docs/contributing/architecture.md → apps/kilocode-docs/docs/contributing/architecture/index.md

@@ -1,5 +1,5 @@
 ---
-sidebar_position: 2
+sidebar_position: 1
 title: "Architecture Overview"
 ---
 
@@ -13,85 +13,51 @@ Kilo Code is a VS Code extension built with TypeScript that connects to various
 
 ```
 ┌─────────────────────────────────────────────────────────────────────┐
-│                           VS Code Extension                          
+│                           VS Code Extension                         │
 ├─────────────────────────────────────────────────────────────────────┤
-│                                                                      
+│                                                                     │
 │  ┌──────────────────┐     ┌──────────────────┐                      │
 │  │   Extension Host │     │    Webview UI    │                      │
 │  │      (src/)      │◀───▶│  (webview-ui/)   │                      │
 │  └────────┬─────────┘     └──────────────────┘                      │
-│           │                                                          
-│           │ Messages                                                 
-│           ▼                                                          
+│           │                                                         │
+│           │ Messages                                                │
+│           ▼                                                         │
 │  ┌──────────────────────────────────────────────────────────────┐   │
-│  │                      Core Services                            │   │
+│  │                      Core Services                           │   │
 │  ├────────────┬────────────┬────────────┬───────────────────────┤   │
 │  │   Tools    │   Browser  │    MCP     │    Code Index         │   │
 │  │  Service   │   Session  │  Servers   │     Service           │   │
 │  └────────────┴────────────┴────────────┴───────────────────────┘   │
-│           │                                                          
-│           │ API Calls                                                
-│           ▼                                                          
+│           │                                                         │
+│           │ API Calls                                               │
+│           ▼                                                         │
 │  ┌──────────────────────────────────────────────────────────────┐   │
-│  │                   API Provider Layer                          │   │
+│  │                   API Provider Layer                         │   │
 │  ├────────────┬────────────┬────────────┬───────────────────────┤   │
 │  │  Anthropic │   OpenAI   │   Kilo     │     OpenRouter        │   │
 │  │    API     │    API     │ Provider   │        API            │   │
 │  └────────────┴────────────┴────────────┴───────────────────────┘   │
-│                                                                      
+│                                                                     │
 └─────────────────────────────────────────────────────────────────────┘
 ```
 
-## Key Components
+### Features
 
-### Extension Host (`src/`)
+These pages document the architecture and design of a current or planned feature, as well as any unique development patterns.
 
-The extension host runs in Node.js within VS Code and contains:
+| Feature                                                            | Description                                |
+| ------------------------------------------------------------------ | ------------------------------------------ |
+| [Annual Billing](./annual-billing.md)                              | Annual subscription billing                |
+| [Enterprise MCP Controls](./enterprise-mcp-controls.md)            | Admin controls for MCP server allowlists   |
+| [Onboarding Improvements](./onboarding-engagement-improvements.md) | User onboarding and engagement features    |
+| [Organization Modes Library](./organization-modes-library.md)      | Shared modes for teams and enterprise      |
+| [Agentic Security Reviews](./security-reviews.md)                  | AI-powered security vulnerability analysis |
+| [Track Repo URL](./track-repo-url.md)                              | Usage tracking by repository/project       |
+| [Vercel AI Gateway](./vercel-ai-gateway.md)                        | Vercel AI Gateway integration              |
+| [Voice Transcription](./voice-transcription.md)                    | Live voice input for chat                  |
 
-- **`src/core/`** - The agent loop and core logic
-    - `Kilo.ts` - Main agent class that orchestrates interactions
-    - `prompts/` - System prompts and prompt construction
-    - `tools/` - Tool implementations (file operations, search, etc.)
-- **`src/services/`** - Service implementations
-
-    - `browser/` - Puppeteer-based browser automation
-    - `checkpoints/` - Git-based state checkpoints
-    - `code-index/` - Codebase indexing and semantic search
-    - `mcp/` - Model Context Protocol server integration
-    - `commit-message/` - Git commit message generation
-
-- **`src/api/`** - API provider implementations
-
-    - Handles communication with AI providers
-    - Manages streaming responses
-    - Implements provider-specific features
-
-- **`src/activate/`** - Extension activation and command registration
-
-### Webview UI (`webview-ui/`)
-
-A React-based frontend that provides the chat interface:
-
-- Built with React and TypeScript
-- Uses VS Code's webview API
-- Communicates with extension host via message passing
-- Styled with Tailwind CSS
-
-### Shared Packages (`packages/`)
-
-Shared code used across the monorepo:
-
-- `@kilocode/types` - Shared TypeScript types
-- `@kilocode/telemetry` - Telemetry utilities
-
-### Applications (`apps/`)
-
-- `kilocode-docs` - This documentation site (Docusaurus)
-- `kilocode-website` - Marketing website
-
-### Command-Line Interface (`cli/`)
-
-A standalone CLI for running Kilo Code outside of VS Code.
+To propose a new feature design, consider using the [feature template](./feature-template.md).
 
 ## Key Concepts
 
@@ -191,5 +157,4 @@ The project uses:
 ## Further Reading
 
 - [Development Environment](/contributing/development-environment) - Setup guide
-- [Engineering Specs](/contributing/specs) - Technical specifications
 - [Tools Reference](/features/tools/tool-use-overview) - Available tools

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-onboarding-engagement-improvements.md → apps/kilocode-docs/docs/contributing/architecture/onboarding-engagement-improvements.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 5
-title: "Spec: Improve Onboarding Flow"
+title: "Improve Onboarding Flow"
 ---
 
-# SPEC: Kilo Code Onboarding & User Engagement Improvements
+# Kilo Code Onboarding & User Engagement Improvements
 
 # Overview
 

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-organization-modes-library.md → apps/kilocode-docs/docs/contributing/architecture/organization-modes-library.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 6
-title: "Spec: Organization Modes Library"
+title: "Organization Modes Library"
 ---
 
-# Spec: Organization Modes Library
+# Organization Modes Library
 
 # Overview
 

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-security-reviews.md → apps/kilocode-docs/docs/contributing/architecture/security-reviews.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 7
-title: "Spec: Agentic Security Reviews"
+title: "Agentic Security Reviews"
 ---
 
-# SPEC: Agentic Security Reviews
+# Agentic Security Reviews
 
 ## Overview
 

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-track-repo-url.md → apps/kilocode-docs/docs/contributing/architecture/track-repo-url.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 8
-title: "Spec: Track Usage by Repository URL"
+title: "Track Usage by Repository URL"
 ---
 
-# Spec: Track Usage by Project
+# Track Usage by Project
 
 # Overview
 

+ 77 - 0
apps/kilocode-docs/docs/contributing/architecture/vercel-ai-gateway.md

@@ -0,0 +1,77 @@
+---
+sidebar_position: 9
+title: "Vercel AI Gateway"
+---
+
+# OpenRouter and Vercel AI Gateway API compatibility
+
+Both OpenRouter and Vercel AI Gateway provide an OpenAI-compatible API.
+They are largely compatible and Vercel even adopted some of OpenRouter's non-standard extensions.
+
+OpenRouter API docs: https://openrouter.ai/docs/api/reference/overview
+
+Vercel AI Gateway API docs: https://vercel.com/docs/ai-gateway/openai-compat
+
+At time of writing, OpenRouter provides beta support for the Responses API, but Vercel does not: https://openrouter.ai/docs/api/reference/responses/overview
+
+## Available models and identifiers
+
+OpenRouter has more models than Vercel. The naming scheme is similar, sometimes identical but not always. For example `x-ai/grok-code-fast-1` (OpenRouter) has a different prefix from `xai/grok-code-fast-1` (Vercel). We will have to come up with a mapping from OpenRouter to Vercel model identifiers.
+
+- https://openrouter.ai/models
+- https://vercel.com/ai-gateway/models
+
+## Reasoning
+
+Vercel seems to have adopted OpenRouter's (non-standard) reasoning configuration:
+
+- https://openrouter.ai/docs/api/reference/responses/reasoning#reasoning-configuration
+- https://vercel.com/docs/ai-gateway/openai-compat#reasoning-configuration
+
+Both Vercel and OpenRouter use the same `reasoning` property for reasoning content (the standard is `reasoning_content`, although our extension will accept both):
+
+- https://openrouter.ai/docs/api/api-reference/chat/send-chat-completion-request#response.body.choices.message.reasoning
+- https://vercel.com/docs/ai-gateway/openai-compat#response-format-with-reasoning
+
+Vercel supports OpenRouter's way of preserving reasoning details in the Chat Completions API:
+
+- https://openrouter.ai/docs/guides/best-practices/reasoning-tokens#preserving-reasoning-blocks
+- https://vercel.com/docs/ai-gateway/openai-compat#preserving-reasoning-details-across-providers
+
+Other providers would require use of the Responses API (e.g. xAI) or Anthropic API (e.g. MiniMax)
+
+## Provider configuration
+
+OpenRouter's and Vercel's provider configuration are different:
+
+- https://openrouter.ai/docs/guides/routing/provider-selection
+- https://vercel.com/docs/ai-gateway/openai-compat#provider-options
+
+We will likely support OpenRouter's and convert between the two.
+
+Inference provider identifiers appear similar at first glance, but they may not always be identical.
+
+## Cost calculation
+
+Whether Vercel includes cost in the response (like OpenRouter) is unclear. In the docs there's an embeddings example, which suggests that it does, but in a different format than OpenRouter:
+
+- https://vercel.com/docs/ai-gateway/openai-compat#embeddings
+
+We may have to estimate the cost in the extension instead.
+
+There's a generation endpoint, which looks very similar to OpenRouter's at first glance:
+
+- https://openrouter.ai/docs/api/api-reference/generations/get-generation
+- https://vercel.com/docs/ai-gateway/usage#generation-lookup
+
+# Deciding where to route traffic
+
+We want to route some traffic to Vercel, ideally just enough so we can be first place on both leaderboards. However, we will initially start with a small portion of traffic < 5% and will evaluate whether it make sense to increase volume.
+
+Vercel will also act as fallback if we encounter issues with OpenRouter (such as the issue with Grok Code Fast and OpenRouter recently). We need the ability to route certain providers and / or models to Vercel vs OpenRouter.
+
+Requests from the same user for the same model should go to the same gateway for caching purposes.
+
+We can randomize users to a gateway in a way similar to what was done for autocomplete: https://github.com/Kilo-Org/kilocode/pull/3857
+
+Since not all models are available on Vercel, some traffic will have to go to OpenRouter regardless.

+ 2 - 2
apps/kilocode-docs/docs/contributing/specs/spec-voice-transcription.md → apps/kilocode-docs/docs/contributing/architecture/voice-transcription.md

@@ -1,9 +1,9 @@
 ---
 sidebar_position: 10
-title: "Spec: Live Voice Transcription"
+title: "Live Voice Transcription"
 ---
 
-# SPEC: Live Voice Transcription
+# Live Voice Transcription
 
 # Overview
 

+ 3 - 3
apps/kilocode-docs/docs/contributing/index.md

@@ -24,7 +24,7 @@ Setting Up the Development Environment is described in details on the [Developme
 
 ## Understanding the Architecture
 
-Before diving into the code, we recommend reviewing the [Architecture Overview](/contributing/architecture) to understand how the different components of Kilo Code fit together.
+Before diving into the code, we recommend reviewing the [Architecture Overview](architecture) to understand how the different components of Kilo Code fit together.
 
 ## Development Workflow
 
@@ -82,7 +82,7 @@ git checkout -b your-branch-name
 
 Custom modes are a powerful way to extend Kilo Code's capabilities. To create and share a custom mode:
 
-1. Follow the [Custom Modes documentation](/features/custom-modes) to create your mode
+1. Follow the [Custom Modes documentation](/agent-behavior/custom-modes) to create your mode
 
 2. Test your mode thoroughly
 
@@ -90,7 +90,7 @@ Custom modes are a powerful way to extend Kilo Code's capabilities. To create an
 
 ## Engineering Specs
 
-For larger features, we write engineering specs to align on requirements before implementation. Check out the [Engineering Specs](/contributing/specs) section to see planned features and learn how to contribute specs.
+For larger features, we write engineering specs to align on requirements before implementation. Check out the [Architecture](/contributing/architecture) section to see planned features and learn how to contribute specs.
 
 ## Documentation Contributions
 

+ 0 - 48
apps/kilocode-docs/docs/contributing/specs/index.md

@@ -1,48 +0,0 @@
----
-sidebar_position: 1
-title: "Engineering Specs"
----
-
-# Engineering Specs
-
-Engineering specs are technical documents that describe how we plan to implement features and solve problems. They help us align on requirements, communicate progress, and document our architectural decisions.
-
-## Why Write Specs?
-
-As the company gets bigger and gains adoption, it's important to evolve how we work together. There are more teams and more stakeholders than ever, and with that, more opportunities for mis-communication and untimely disagreements.
-
-Writing specs for reasonably complicated projects has many benefits:
-
-- Improves clarity of implementation
-- Reduces time to implementation
-    - Often times, after a spec is written, it's fed into an LLM to implement the changes
-- Allows for discussion (and maybe some healthy bike shedding) prior to implementation
-    - Importantly, aligns on requirements prior to implementation
-- Communicates upward and outward
-    - Helps leadership understand the progress of a project
-    - Helps teammates understand how various parts of our application is architected
-
-It is useful to start with an outline/template for specs. For that, refer to the [SPEC: Template](./spec-template.md) document.
-
-## Current Specs
-
-| Spec                                                                    | Description                                |
-| ----------------------------------------------------------------------- | ------------------------------------------ |
-| [Enterprise MCP Controls](./spec-enterprise-mcp-controls.md)            | Admin controls for MCP server allowlists   |
-| [Onboarding Improvements](./spec-onboarding-engagement-improvements.md) | User onboarding and engagement features    |
-| [Organization Modes Library](./spec-organization-modes-library.md)      | Shared modes for teams and enterprise      |
-| [Agentic Security Reviews](./spec-security-reviews.md)                  | AI-powered security vulnerability analysis |
-| [Track Repo URL](./spec-track-repo-url.md)                              | Usage tracking by repository/project       |
-| [Voice Transcription](./spec-voice-transcription.md)                    | Live voice input for chat                  |
-
-Private specs, for example backend non-user facing features, can be found on the [company handbook (Kilo internal)](https://handbook.kilo.ai/engineering/specs/why-specs).
-
-## Contributing a Spec
-
-If you're working on a significant feature, consider writing a spec:
-
-1. Copy the [Spec Template](./spec-template.md)
-2. Fill in the sections with your proposal
-3. Submit a PR for review
-4. Discuss and iterate with the team
-5. Once approved, create GitHub issues from the implementation plan

+ 1 - 1
apps/kilocode-docs/docs/faq.md

@@ -113,7 +113,7 @@ Open the Kilo Code panel (<img src="/docs/img/kilo-v1.svg" width="12" />) and ty
 - **Architect:** For planning and technical leadership.
 - **Ask:** For answering questions and providing information.
 - **Debug:** For systematic problem diagnosis.
-  You can also create [Custom Modes](/features/custom-modes).
+  You can also create [Custom Modes](/agent-behavior/custom-modes).
 
 ### How do I switch between modes?
 

+ 4 - 4
apps/kilocode-docs/docs/features/api-configuration-profiles.md

@@ -38,15 +38,15 @@ Note that available settings vary by provider and model. Each provider offers di
       <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="Provider selection dropdown" width="550" />
     - Enter API key
 
-                 <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API key entry field" width="550" />
+                   <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API key entry field" width="550" />
 
     - Choose a model
 
-                 <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="Model selection interface" width="550" />
+                   <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="Model selection interface" width="550" />
 
     - Adjust model parameters
 
-                 <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="Model parameter adjustment controls" width="550" />
+                   <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="Model parameter adjustment controls" width="550" />
 
 ### Switching Profiles
 
@@ -98,7 +98,7 @@ API keys are stored securely in VSCode's Secret Storage and are never exposed in
 
 ## Related Features
 
-- Works with [custom modes](/features/custom-modes) you create
+- Works with [custom modes](/agent-behavior/custom-modes) you create
 - Integrates with [local models](/advanced-usage/local-models) for offline work
 - Supports [temperature settings](/features/model-temperature) per mode
 - Enhances cost management with [rate limits and usage tracking](/advanced-usage/rate-limits-costs)

+ 1 - 1
apps/kilocode-docs/docs/features/auto-launch-configuration.md

@@ -48,7 +48,7 @@ This happens seamlessly in the background, requiring no manual intervention.
     - `"ask"` - Questions and explanations
     - `"debug"` - Problem diagnosis and troubleshooting
     - `"test"` - Testing-focused workflows
-    - Custom mode slugs (if you have [custom modes](/features/custom-modes))
+    - Custom mode slugs (if you have [custom modes](/agent-behavior/custom-modes))
 
 ## Example Configurations
 

+ 109 - 0
apps/kilocode-docs/docs/features/mcp/using-mcp-in-cli.md

@@ -0,0 +1,109 @@
+---
+title: Using MCP in the CLI
+sidebar_label: Using MCP in CLI
+---
+
+# Using MCP in the CLI
+
+The Kilo Code CLI supports MCP servers, but uses a **different configuration path** than the VS Code extension.
+
+## Configuration Location
+
+| Environment | MCP Settings Path                                   |
+| ----------- | --------------------------------------------------- |
+| **CLI**     | `~/.kilocode/cli/global/settings/mcp_settings.json` |
+| **VS Code** | VS Code's global storage directory                  |
+
+MCP servers configured in VS Code are **not** automatically available in the CLI. You must configure them separately.
+
+## Configuration Format
+
+Edit `~/.kilocode/cli/global/settings/mcp_settings.json`:
+
+```json
+{
+	"mcpServers": {
+		"server-name": {
+			"command": "node",
+			"args": ["/path/to/server.js"],
+			"env": {
+				"API_KEY": "your_api_key"
+			},
+			"alwaysAllow": ["tool1", "tool2"],
+			"disabled": false
+		}
+	}
+}
+```
+
+## Transport Types
+
+### STDIO (Local Servers)
+
+```json
+{
+	"mcpServers": {
+		"local-server": {
+			"command": "node",
+			"args": ["/path/to/server.js"],
+			"env": {}
+		}
+	}
+}
+```
+
+### Streamable HTTP (Remote Servers)
+
+```json
+{
+	"mcpServers": {
+		"remote-server": {
+			"type": "streamable-http",
+			"url": "https://your-server.com/mcp",
+			"headers": {
+				"Authorization": "Bearer token"
+			}
+		}
+	}
+}
+```
+
+## Project-Level Configuration
+
+You can define MCP servers per-project by creating `.kilocode/mcp.json` in your project root. Project-level servers take precedence over global settings.
+
+## Configuration Options
+
+| Option        | Description                                                 |
+| ------------- | ----------------------------------------------------------- |
+| `command`     | Executable to run (STDIO)                                   |
+| `args`        | Command arguments (STDIO)                                   |
+| `env`         | Environment variables                                       |
+| `type`        | Transport type: `stdio` (default), `streamable-http`, `sse` |
+| `url`         | Server URL (HTTP transports)                                |
+| `headers`     | HTTP headers (HTTP transports)                              |
+| `alwaysAllow` | Array of tool names to auto-approve                         |
+| `disabled`    | Set `true` to disable without removing                      |
+| `timeout`     | Request timeout in seconds (default: 60)                    |
+
+## Auto-Approval
+
+MCP auto-approval is controlled via CLI config (`kilocode config`):
+
+```json
+{
+	"autoApproval": {
+		"mcp": {
+			"enabled": true
+		}
+	}
+}
+```
+
+Or via environment variable:
+
+```bash
+export KILO_AUTO_APPROVAL_MCP_ENABLED=true
+```
+
+Per-tool auto-approval uses the `alwaysAllow` array in the server configuration.

+ 2 - 2
apps/kilocode-docs/docs/features/model-temperature.md

@@ -89,5 +89,5 @@ Remember that different models may respond differently to the same temperature v
 ## Related Features
 
 - Works with all [API providers](/providers/openai) supported by Kilo Code
-- Complements [custom instructions](/advanced-usage/custom-instructions) for fine-tuning responses
-- Works alongside [custom modes](/features/custom-modes) you create
+- Complements [custom instructions](/agent-behavior/custom-instructions) for fine-tuning responses
+- Works alongside [custom modes](/agent-behavior/custom-modes) you create

+ 6 - 6
apps/kilocode-docs/docs/index.mdx

@@ -56,7 +56,7 @@ Kilo Code adapts to your needs with specialized [modes](/basic-usage/using-modes
 - [**Architect Mode:**](/basic-usage/using-modes#architect-mode) For planning and technical leadership
 - [**Ask Mode:**](/basic-usage/using-modes#ask-mode) For answering questions and providing information
 - [**Debug Mode:**](/basic-usage/using-modes#debug-mode) For systematic problem diagnosis
-- **[Custom Modes](/features/custom-modes):** Create unlimited specialized personas for security auditing, performance optimization, documentation, or any other task
+- **[Custom Modes](/agent-behavior/custom-modes):** Create unlimited specialized personas for security auditing, performance optimization, documentation, or any other task
 
 #### Core Tools
 
@@ -79,10 +79,10 @@ See the complete [Tools Reference](/features/tools/tool-use-overview) for all av
 
 Make Kilo Code work your way with:
 
-- [Settings Management](/features/settings-management) for configuring your experience
-- [Custom Modes](/features/custom-modes) for specialized tasks
-- [Custom Rules](/advanced-usage/custom-rules) for project-specific rules
-- [Custom Instructions](/advanced-usage/custom-instructions) for global plugin-wide instructions
+- [Settings Management](/basic-usage/settings-management) for configuring your experience
+- [Custom Modes](/agent-behavior/custom-modes) for specialized tasks
+- [Custom Rules](/agent-behavior/custom-rules) for project-specific rules
+- [Custom Instructions](/agent-behavior/custom-instructions) for global plugin-wide instructions
 - [API Configuration Profiles](/features/api-configuration-profiles) for different model providers
 - [Auto-Approval Settings](/features/auto-approving-actions) for faster workflows
 
@@ -92,7 +92,7 @@ Make Kilo Code work your way with:
 
 - [Using Kilo Code](/basic-usage/the-chat-interface) - Learn the basics
 - [Core Concepts](/features/auto-approving-actions) - Master key features
-- [Advanced Usage](/advanced-usage/prompt-engineering) - Take your skills further
+- [Advanced Usage](/agent-behavior/prompt-engineering) - Take your skills further
 - [Frequently Asked Questions](/faq) - Get answers to common questions
 
 ### Community

+ 9 - 4
apps/kilocode-docs/docs/providers/bedrock.md

@@ -4,7 +4,7 @@ sidebar_label: AWS Bedrock
 
 # Using AWS Bedrock With Kilo Code
 
-Kilo Code supports accessing models through Amazon Bedrock, a fully managed service that makes a selection of high-performing foundation models (FMs) from leading AI companies available via a single API.
+Kilo Code supports accessing models through Amazon Bedrock, a fully managed service that makes a selection of high-performing foundation models (FMs) from leading AI companies available via a single API. This provider connects directly to AWS Bedrock and authenticates with the provided credentials.
 
 **Website:** [https://aws.amazon.com/bedrock/](https://aws.amazon.com/bedrock/)
 
@@ -20,13 +20,16 @@ Kilo Code supports accessing models through Amazon Bedrock, a fully managed serv
 
 ## Getting Credentials
 
-You have two main options for configuring AWS credentials:
+You have three options for configuring AWS credentials:
 
-1.  **AWS Access Keys (Recommended for Development):**
+1.  **Bedrock API Key:**
+    - Create a Bedrock-specific API key in the AWS Console. This is a simple service-specific authentication method.
+    - See the [AWS documentation on Bedrock credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bedrock.html) for instructions on creating an API key.
+2.  **AWS Access Keys (Recommended for Development):**
     - Create an IAM user with the necessary permissions (at least `bedrock:InvokeModel`).
     - Generate an access key ID and secret access key for that user.
     - _(Optional)_ Create a session token if required by your IAM configuration.
-2.  **AWS Profile:**
+3.  **AWS Profile:**
     - Configure an AWS profile using the AWS CLI or by manually editing your AWS credentials file. See the [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) for details.
 
 ## Supported Models
@@ -75,6 +78,8 @@ Refer to the [Amazon Bedrock documentation](https://docs.aws.amazon.com/bedrock/
 1.  **Open Kilo Code Settings:** Click the gear icon (<Codicon name="gear" />) in the Kilo Code panel.
 2.  **Select Provider:** Choose "Bedrock" from the "API Provider" dropdown.
 3.  **Select Authentication Method:**
+    - **Bedrock API Key:**
+        - Enter your Bedrock API key directly. This is the simplest setup option.
     - **AWS Credentials:**
         - Enter your "AWS Access Key" and "AWS Secret Key."
         - (Optional) Enter your "AWS Session Token" if you're using temporary credentials.

+ 2 - 1
apps/kilocode-docs/docs/providers/cerebras.md

@@ -20,7 +20,8 @@ Cerebras is known for their ultra-fast AI inference powered by the Cerebras CS-3
 Kilo Code supports the following Cerebras models:
 
 - `gpt-oss-120b` (Default) – High-performance open-source model optimized for fast inference
-- `zai-glm-4.6` – Advanced GLM model with enhanced reasoning capabilities
+- `zai-glm-4.6` – Fast general-purpose model on Cerebras (up to 1,000 tokens/s). To be deprecated soon.
+- `zai-glm-4.7` – Highly capable general-purpose model on Cerebras (up to 1,000 tokens/s), competitive with leading proprietary models on coding tasks.
 
 Refer to the [Cerebras documentation](https://docs.cerebras.ai/) for detailed information on model capabilities and performance characteristics.
 

+ 1 - 1
apps/kilocode-docs/docs/tips-and-tricks.md

@@ -5,7 +5,7 @@ A collection of quick tips to help you get the most out of Kilo Code.
 - Drag Kilo Code to the [Secondary Sidebar](https://code.visualstudio.com/api/ux-guidelines/sidebars#secondary-sidebar) so you can see the Explorer, Search, Source Control, etc.
 - Once you have Kilo Code in a separate sidebar from the file explorer, you can drag files from the explorer into the chat window (and even multiple at once). Just make sure to hold down the shift key after you start dragging the files.
 - If you're not using [MCP](/features/mcp/overview), turn it off in the <Codicon name="notebook" /> Prompts tab to significantly cut down the size of the system prompt.
-- To keep your [custom modes](/features/custom-modes) on track, limit the types of files that they're allowed to edit.
+- To keep your [custom modes](/agent-behavior/custom-modes) on track, limit the types of files that they're allowed to edit.
 - If you hit the dreaded `input length and max tokens exceed context limit` error, you can recover by deleting a message, rolling back to a previous checkpoint, or switching over to a model with a long context window like Gemini for a message.
 - In general, be thoughtful about your `Max Tokens` setting for thinking models. Every token you allocate to that takes away from space available to store conversation history. Consider only using high `Max Tokens` / `Max Thinking Tokens` settings with modes like Architect and Debug, and keeping Code mode at 16k max tokens or less.
 - If there's a real world job posting for something you want a custom mode to do, try asking Code mode to `Create a custom mode based on the job posting at @[url]`

+ 39 - 4
apps/kilocode-docs/docusaurus.config.ts

@@ -97,6 +97,17 @@ const config: Config = {
 		[
 			"@docusaurus/plugin-client-redirects",
 			{
+				createRedirects(existingPath) {
+					// Redirect old /contributing/specs/spec-* paths to /contributing/architecture/*
+					if (existingPath.startsWith("/contributing/architecture/")) {
+						const filename = existingPath.replace("/contributing/architecture/", "")
+						return [
+							`/contributing/specs/spec-${filename}`, // spec- prefix
+							`/contributing/specs/${filename}`, // without prefix
+						]
+					}
+					return undefined
+				},
 				redirects: [
 					// Files moved from advanced-usage to features
 					{
@@ -108,12 +119,36 @@ const config: Config = {
 						from: ["/advanced-usage/code-actions"],
 					},
 					{
-						to: "/advanced-usage/custom-instructions",
-						from: ["/features/custom-instructions"],
+						to: "/agent-behavior/custom-instructions",
+						from: [
+							"/advanced-usage/custom-instructions",
+							"/features/custom-instructions",
+							"/customization/custom-instructions",
+						],
+					},
+					{
+						to: "/agent-behavior/custom-modes",
+						from: ["/features/custom-modes", "/advanced-usage/custom-modes", "/customization/custom-modes"],
+					},
+					{
+						to: "/agent-behavior/custom-rules",
+						from: ["/advanced-usage/custom-rules", "/customization/custom-rules"],
+					},
+					{
+						to: "/agent-behavior/skills",
+						from: ["/features/skills", "/customization/skills"],
+					},
+					{
+						to: "/agent-behavior/workflows",
+						from: ["/features/slash-commands/workflows", "/customization/workflows"],
+					},
+					{
+						to: "/basic-usage/settings-management",
+						from: ["/features/settings-management", "/customization/settings-management"],
 					},
 					{
-						to: "/features/custom-modes",
-						from: ["/advanced-usage/custom-modes"],
+						to: "/agent-behavior/prompt-engineering",
+						from: ["/advanced-usage/prompt-engineering"],
 					},
 					{
 						to: "/features/enhance-prompt",

+ 4 - 4
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/custom-instructions.md

@@ -7,7 +7,7 @@
 自定义指令定义了扩展的特定行为、偏好和约束,超出了 Kilo 的基本角色定义。示例包括编码风格、文档标准、测试要求和工作流指南。
 
 :::info 自定义指令 vs 规则
-自定义指令是 IDE 范围的,适用于所有工作区,无论你在处理哪个项目,都会保持你的偏好。与指令不同,[自定义规则](/advanced-usage/custom-rules.md) 是项目特定的,允许你设置基于工作区的规则集。
+自定义指令是 IDE 范围的,适用于所有工作区,无论你在处理哪个项目,都会保持你的偏好。与指令不同,[自定义规则](/agent-behavior/custom-rules) 是项目特定的,允许你设置基于工作区的规则集。
 :::
 
 ## 设置自定义指令
@@ -36,7 +36,7 @@
 
 ## 相关功能
 
-- [自定义模式](/features/custom-modes)
-- [自定义规则](/advanced-usage/custom-rules)
-- [设置管理](/features/settings-management)
+- [自定义模式](/agent-behavior/custom-modes)
+- [自定义规则](/agent-behavior/custom-rules)
+- [设置管理](/basic-usage/settings-management)
 - [自动批准设置](/features/auto-approving-actions)

+ 3 - 3
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/custom-rules.md

@@ -211,7 +211,7 @@ Kilo Code 提供了一个内置界面,用于管理您的自定义规则,而
 
 ## 相关功能
 
-- [自定义模式](/features/custom-modes)
-- [自定义指令](/advanced-usage/custom-instructions)
-- [设置管理](/features/settings-management)
+- [自定义模式](/agent-behavior/custom-modes)
+- [自定义指令](/agent-behavior/custom-instructions)
+- [设置管理](/basic-usage/settings-management)
 - [自动批准设置](/features/auto-approving-actions)

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/memory-bank.md

@@ -31,7 +31,7 @@ Memory Bank 是一个结构化文档系统,使 Kilo Code 能够**更好地理
 
 ## Memory Bank 的工作原理
 
-Memory Bank 基于 Kilo Code 的 [自定义规则](/advanced-usage/custom-rules) 功能构建,为项目文档提供了一个专门的框架。Memory Bank 文件是存储在项目仓库 `.kilocode/rules/memory-bank` 文件夹中的标准 Markdown 文件。它们不是隐藏或专有的——它们是你和 Kilo Code 都可以访问的常规文档文件。
+Memory Bank 基于 Kilo Code 的 [自定义规则](/agent-behavior/custom-rules) 功能构建,为项目文档提供了一个专门的框架。Memory Bank 文件是存储在项目仓库 `.kilocode/rules/memory-bank` 文件夹中的标准 Markdown 文件。它们不是隐藏或专有的——它们是你和 Kilo Code 都可以访问的常规文档文件。
 
 在每个任务开始时,Kilo Code 会读取所有 Memory Bank 文件,以构建对项目的全面理解。这是自动进行的,不需要你采取任何操作。Kilo Code 然后会在其响应的开头显示 `[Memory Bank: Active]`,表示 Memory Bank 已成功激活,并简要总结其对项目的理解。
 

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/advanced-usage/prompt-engineering.md

@@ -44,7 +44,7 @@ Prompt engineering 是为 AI 模型(如 Kilo Code)编写有效指令的艺
 - 定义项目特定的约定。
 - 调整 Kilo Code 的语气或个性。
 
-有关更多详细信息,请参阅 [自定义指令](/advanced-usage/custom-instructions) 部分。
+有关更多详细信息,请参阅 [自定义指令](/agent-behavior/custom-instructions) 部分。
 
 ## 处理歧义
 

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/basic-usage/git-commit-generation.md

@@ -154,4 +154,4 @@ git add .
 ## 相关功能
 
 - [API 配置配置文件](/features/api-configuration-profiles) - 使用不同的模型进行提交信息生成
-- [设置管理](/features/settings-management) - 管理您的所有 Kilo Code 首选项
+- [设置管理](/basic-usage/settings-management) - 管理您的所有 Kilo Code 首选项

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/basic-usage/using-modes.md

@@ -87,4 +87,4 @@ Kilo Code 中的模式是专门设计的角色,可以根据当前任务调整
 
 ## 自定义模式
 
-通过定义工具访问权限、文件权限和行为指令,创建你自己的专业助手。自定义模式有助于执行团队标准或创建特定用途的助手。有关设置说明,请参阅 [自定义模式文档](/features/custom-modes)。
+通过定义工具访问权限、文件权限和行为指令,创建你自己的专业助手。自定义模式有助于执行团队标准或创建特定用途的助手。有关设置说明,请参阅 [自定义模式文档](/agent-behavior/custom-modes)。

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/extending/contributing-to-kilo.md

@@ -73,7 +73,7 @@ git checkout -b your-branch-name
 
 自定义模式是扩展 Kilo Code 功能的强大方式。要创建并分享自定义模式:
 
-1. 按照 [自定义模式文档](/features/custom-modes) 创建你的模式
+1. 按照 [自定义模式文档](/agent-behavior/custom-modes) 创建你的模式
 
 2. 彻底测试你的模式
 

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/faq.md

@@ -103,7 +103,7 @@ Kilo Code支持多种API提供商,包括:
 - **Architect模式:** 用于规划和技术领导
 - **Ask模式:** 用于回答问题并提供信息
 - **Debug模式:** 用于系统化问题诊断
-  你还可以创建[自定义模式](/features/custom-modes)。
+  你还可以创建[自定义模式](/agent-behavior/custom-modes)。
 
 ### 如何在模式之间切换?
 

+ 5 - 5
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/features/api-configuration-profiles.md

@@ -36,19 +36,19 @@ API 配置配置文件允许您创建和切换不同的 AI 设置集。每个配
 
     - 选择您的 API 提供商
 
-                          <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="提供商选择下拉菜单" width="550" />
+                            <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-2.png" alt="提供商选择下拉菜单" width="550" />
 
     - 输入 API 密钥
 
-                          <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API 密钥输入字段" width="550" />
+                            <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-3.png" alt="API 密钥输入字段" width="550" />
 
     - 选择模型
 
-                          <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="模型选择界面" width="550" />
+                            <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-8.png" alt="模型选择界面" width="550" />
 
     - 调整模型参数
 
-                          <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="模型参数调整控件" width="550" />
+                            <img src="/docs/img/api-configuration-profiles/api-configuration-profiles-5.png" alt="模型参数调整控件" width="550" />
 
 ### 切换配置文件
 
@@ -100,7 +100,7 @@ API 密钥安全地存储在 VSCode 的 Secret Storage 中,绝不会以纯文
 
 ## 相关功能
 
-- 适用于您创建的[自定义模式](/features/custom-modes)
+- 适用于您创建的[自定义模式](/agent-behavior/custom-modes)
 - 与[本地模型](/advanced-usage/local-models)集成以进行离线工作
 - 支持每个模式的[温度设置](/features/model-temperature)
 - 通过[速率限制和使用跟踪](/advanced-usage/rate-limits-costs)增强成本管理

+ 2 - 2
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/features/model-temperature.md

@@ -89,5 +89,5 @@ Kilo Code 在实现温度处理时考虑了以下因素:
 ## 相关功能
 
 - 适用于 Kilo Code 支持的所有 [API 提供商](/providers/openai)
-- 补充[自定义指令](/advanced-usage/custom-instructions)以微调响应
-- 与您创建的[自定义模式](/features/custom-modes)一起使用
+- 补充[自定义指令](/agent-behavior/custom-instructions)以微调响应
+- 与您创建的[自定义模式](/agent-behavior/custom-modes)一起使用

+ 6 - 6
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/index.mdx

@@ -52,7 +52,7 @@ Kilo Code 通过专门的[模式](/basic-usage/using-modes)适应你的需求:
 - [**Architect 模式:**](/basic-usage/using-modes#architect-mode) 用于规划和技术领导
 - [**Ask 模式:**](/basic-usage/using-modes#ask-mode) 用于回答问题并提供信息
 - [**Debug 模式:**](/basic-usage/using-modes#debug-mode) 用于系统化问题诊断
-- **[自定义模式](/features/custom-modes):** 创建无限数量的专门角色,用于安全审计、性能优化、文档编写或任何其他任务
+- **[自定义模式](/agent-behavior/custom-modes):** 创建无限数量的专门角色,用于安全审计、性能优化、文档编写或任何其他任务
 
 #### 核心工具
 
@@ -75,10 +75,10 @@ Kilo Code 配备了强大的[工具](/features/tools/tool-use-overview),可以
 
 通过以下方式让 Kilo Code 按照你的方式工作:
 
-- [设置管理](/features/settings-management)来配置你的体验
-- [自定义模式](/features/custom-modes)用于专门任务
-- [自定义规则](/advanced-usage/custom-rules)用于项目特定规则
-- [自定义指令](/advanced-usage/custom-instructions)用于全局插件范围内的指令
+- [设置管理](/basic-usage/settings-management)来配置你的体验
+- [自定义模式](/agent-behavior/custom-modes)用于专门任务
+- [自定义规则](/agent-behavior/custom-rules)用于项目特定规则
+- [自定义指令](/agent-behavior/custom-instructions)用于全局插件范围内的指令
 - [API 配置配置文件](/features/api-configuration-profiles)用于不同的模型提供商
 - [自动批准设置](/features/auto-approving-actions)用于更快的工作流程
 
@@ -88,7 +88,7 @@ Kilo Code 配备了强大的[工具](/features/tools/tool-use-overview),可以
 
 - [使用 Kilo Code](/basic-usage/the-chat-interface) - 学习基础知识
 - [核心概念](/features/auto-approving-actions) - 掌握关键功能
-- [高级用法](/advanced-usage/prompt-engineering) - 进一步提升你的技能
+- [高级用法](/agent-behavior/prompt-engineering) - 进一步提升你的技能
 - [常见问题解答](/faq) - 获取常见问题的答案
 
 ### 社区

+ 1 - 1
apps/kilocode-docs/i18n/zh-CN/docusaurus-plugin-content-docs/current/tips-and-tricks.md

@@ -5,7 +5,7 @@
 - 将 Kilo Code 拖到[侧边栏](https://code.visualstudio.com/api/ux-guidelines/sidebars#secondary-sidebar),以便同时查看资源管理器、搜索、源代码控制等。
 - 当 Kilo Code 位于与文件资源管理器分开的侧边栏时,你可以将文件从资源管理器拖到聊天窗口中(甚至可以一次拖多个文件)。只需在开始拖动文件后按住 shift 键。
 - 如果你不使用[MCP](/features/mcp/overview),请在 <Codicon name="notebook" /> 提示选项卡中关闭它,以显著减少系统提示的大小。
-- 为了保持[自定义模式](/features/custom-modes)的正轨,请限制它们可以编辑的文件类型。
+- 为了保持[自定义模式](/agent-behavior/custom-modes)的正轨,请限制它们可以编辑的文件类型。
 - 如果你遇到`input length and max tokens exceed context limit`错误,可以通过删除消息、回滚到之前的检查点或切换到具有长上下文窗口的模型(如 Gemini)来恢复。
 - 一般来说,对于思考模型的`Max Tokens`设置要深思熟虑。你分配的每个 token 都会占用存储对话历史的空间。考虑仅在 Architect 和 Debug 等模式中使用高`Max Tokens` / `Max Thinking Tokens`设置,并将 Code 模式保持在 16k max tokens 或更少。
 - 如果有一个你希望自定义模式完成的任务的真实职位发布,可以尝试要求 Code 模式`根据@[url]的职位发布创建一个自定义模式`。

+ 30 - 26
apps/kilocode-docs/sidebars.ts

@@ -86,6 +86,7 @@ const sidebars: SidebarsConfig = {
 					],
 				},
 				"basic-usage/adding-credits",
+				"basic-usage/settings-management",
 			],
 		},
 		{
@@ -129,21 +130,24 @@ const sidebars: SidebarsConfig = {
 				"plans/migration",
 			],
 		},
+		{
+			type: "category",
+			label: "Agent Behavior",
+			items: [
+				"agent-behavior/prompt-engineering",
+				"agent-behavior/agents-md",
+				"agent-behavior/custom-modes",
+				"agent-behavior/custom-rules",
+				"agent-behavior/custom-instructions",
+				"agent-behavior/workflows",
+				"agent-behavior/skills",
+			],
+		},
 		{
 			type: "category",
 			label: "Advanced Usage",
 			items: [
-				"advanced-usage/prompt-engineering",
-				{
-					type: "category",
-					label: "Customizing Kilo Code",
-					items: [
-						"advanced-usage/custom-rules",
-						"advanced-usage/custom-instructions",
-						"advanced-usage/migrating-from-cursor-windsurf",
-						"features/slash-commands/workflows",
-					],
-				},
+				"advanced-usage/migrating-from-cursor-windsurf",
 				{
 					type: "category",
 					label: "Advanced Context Features",
@@ -178,11 +182,6 @@ const sidebars: SidebarsConfig = {
 				"features/experimental/experimental-features",
 			],
 		},
-		{
-			type: "category",
-			label: "Customization",
-			items: ["features/settings-management", "features/custom-modes", "features/skills"],
-		},
 		{
 			type: "category",
 			label: "Extending Kilo Code",
@@ -194,6 +193,7 @@ const sidebars: SidebarsConfig = {
 					items: [
 						"features/mcp/overview",
 						"features/mcp/using-mcp-in-kilo-code",
+						"features/mcp/using-mcp-in-cli",
 						"features/mcp/what-is-mcp",
 						"features/mcp/server-transports",
 						"features/mcp/mcp-vs-api",
@@ -207,20 +207,24 @@ const sidebars: SidebarsConfig = {
 			label: "Contributing",
 			items: [
 				"contributing/index",
-				"contributing/architecture",
 				"contributing/development-environment",
 				{
 					type: "category",
-					label: "Engineering Specs",
+					label: "Architecture",
 					items: [
-						"contributing/specs/index",
-						"contributing/specs/spec-template",
-						"contributing/specs/spec-enterprise-mcp-controls",
-						"contributing/specs/spec-onboarding-engagement-improvements",
-						"contributing/specs/spec-organization-modes-library",
-						"contributing/specs/spec-security-reviews",
-						"contributing/specs/spec-track-repo-url",
-						"contributing/specs/spec-voice-transcription",
+						{
+							type: "doc",
+							id: "contributing/architecture/index",
+							label: "Overview",
+						},
+						"contributing/architecture/annual-billing",
+						"contributing/architecture/enterprise-mcp-controls",
+						"contributing/architecture/onboarding-engagement-improvements",
+						"contributing/architecture/organization-modes-library",
+						"contributing/architecture/security-reviews",
+						"contributing/architecture/track-repo-url",
+						"contributing/architecture/vercel-ai-gateway",
+						"contributing/architecture/voice-transcription",
 					],
 				},
 			],

+ 2 - 0
apps/storybook/.storybook/preview.ts

@@ -1,6 +1,7 @@
 import type { Preview } from "@storybook/react-vite"
 
 import { withExtensionState } from "../src/decorators/withExtensionState"
+import { withPostMessageMock } from "../src/decorators/withPostMessageMock"
 import { withQueryClient } from "../src/decorators/withQueryClient"
 import { withTheme } from "../src/decorators/withTheme"
 import { withI18n } from "../src/decorators/withI18n"
@@ -49,6 +50,7 @@ const preview: Preview = {
 		withI18n,
 		withQueryClient,
 		withExtensionState,
+		withPostMessageMock,
 		withTheme,
 		withTooltipProvider,
 		withFixedContainment,

+ 43 - 0
apps/storybook/src/decorators/withPostMessageMock.tsx

@@ -0,0 +1,43 @@
+import type { Decorator } from "@storybook/react-vite"
+import React from "react"
+
+type PostMessage = Record<string, unknown>
+
+/**
+ * Decorator to mock VSCode postMessage for components that listen to messages.
+ *
+ * To override in a story, use parameters.postMessages:
+ * ```tsx
+ * export const MyStory: Story = {
+ *   parameters: {
+ *     postMessages: [
+ *       { type: "kilocodeNotificationsResponse", notifications: [...] },
+ *     ],
+ *   },
+ * }
+ * ```
+ *
+ * Multiple messages are sent sequentially
+ */
+export const withPostMessageMock: Decorator = (Story, context) => {
+	const messages = context.parameters?.postMessages as PostMessage[] | undefined
+
+	React.useEffect(() => {
+		if (!messages || messages.length === 0) {
+			return
+		}
+
+		const timers: NodeJS.Timeout[] = []
+		messages.forEach((message, index) => {
+			const event = new MessageEvent("message", { data: message })
+			const timer = setTimeout(() => {
+				window.dispatchEvent(event)
+			})
+			timers.push(timer)
+		})
+
+		return () => timers.forEach(clearTimeout)
+	}, [messages])
+
+	return <Story />
+}

+ 1 - 4
apps/storybook/src/utils/createExtensionStateMock.ts

@@ -17,10 +17,7 @@ export const createExtensionStateMock = (
 ): ExtensionStateContextType => {
 	// Only define properties that Storybook stories actually use
 	const knownProperties: Partial<ExtensionStateContextType> = {
-		// Add properties here as they're needed in stories
-		// For example:
-		// theme: {},
-		// apiConfiguration: null,
+		kilocodeDefaultModel: "claude-sonnet-4",
 	}
 
 	// Merge with overrides

+ 71 - 0
apps/storybook/stories/KilocodeNotifications.stories.tsx

@@ -0,0 +1,71 @@
+import type { Meta, StoryObj } from "@storybook/react-vite"
+import { fn } from "storybook/test"
+import { KilocodeNotifications } from "@/components/kilocode/KilocodeNotifications"
+
+const meta = {
+	title: "Components/KilocodeNotifications",
+	component: KilocodeNotifications,
+	parameters: {
+		extensionState: {
+			dismissedNotificationIds: [],
+		},
+	},
+	args: {
+		onDismiss: fn(),
+	},
+} satisfies Meta<typeof KilocodeNotifications>
+
+export default meta
+type Story = StoryObj<typeof meta>
+
+const defaultNotification = {
+	id: "1",
+	title: "Welcome to Kilo Code!",
+	message: "Get started by setting up your API configuration in the settings.",
+	action: {
+		actionText: "Open Settings",
+		actionURL: "https://example.com/settings",
+	},
+}
+
+export const Default: Story = {
+	parameters: {
+		postMessages: [
+			{
+				type: "kilocodeNotificationsResponse",
+				notifications: [defaultNotification],
+			},
+		],
+	},
+}
+
+export const MultipleNotifications: Story = {
+	parameters: {
+		postMessages: [
+			{
+				type: "kilocodeNotificationsResponse",
+				notifications: [
+					{
+						id: "1",
+						title: "First Notification",
+						message: "This is the first notification in a series.",
+					},
+					{
+						id: "2",
+						title: "Second Notification",
+						message: "You can navigate between notifications using the arrows.",
+					},
+					{
+						id: "3",
+						title: "Third Notification",
+						message: "This is the last notification in this set.",
+						action: {
+							actionText: "Visit Website",
+							actionURL: "https://example.com",
+						},
+					},
+				],
+			},
+		],
+	},
+}

+ 43 - 0
apps/storybook/stories/MicrophoneButton.stories.tsx

@@ -0,0 +1,43 @@
+import type { Meta, StoryObj } from "@storybook/react-vite"
+import { fn } from "storybook/test"
+import { MicrophoneButton } from "@/components/chat/MicrophoneButton"
+import { createTableStory } from "../src/utils/createTableStory"
+
+const meta = {
+	title: "Components/MicrophoneButton",
+	component: MicrophoneButton,
+	parameters: {
+		layout: "centered",
+		backgrounds: {
+			default: "dark",
+			values: [{ name: "dark", value: "#1e1e1e" }],
+		},
+	},
+	args: {
+		isRecording: false,
+		disabled: false,
+		hasError: false,
+		onClick: fn(),
+		onStatusChange: fn(),
+	},
+} satisfies Meta<typeof MicrophoneButton>
+
+export default meta
+type Story = StoryObj<typeof meta>
+
+export const Default: Story = {}
+
+export const States = createTableStory({
+	component: MicrophoneButton,
+	rows: {
+		isRecording: [false, true],
+	},
+	columns: {
+		disabled: [false, true],
+		hasError: [false, true],
+	},
+	defaultProps: {
+		onClick: fn(),
+		onStatusChange: fn(),
+	},
+})

+ 48 - 0
apps/storybook/stories/STTSetupPopover.stories.tsx

@@ -0,0 +1,48 @@
+import type { Meta, StoryObj } from "@storybook/react-vite"
+import { STTSetupPopoverContent } from "@/components/chat/STTSetupPopover"
+
+const meta = {
+	title: "Components/STTSetupPopover",
+	component: STTSetupPopoverContent,
+	parameters: {
+		layout: "centered",
+	},
+	tags: ["autodocs"],
+	render: (args) => (
+		<div className="w-[calc(100vw-32px)] max-w-[400px]">
+			<STTSetupPopoverContent {...args} />
+		</div>
+	),
+	args: {
+		setInputValue: (value: string) => {
+			console.log("setInputValue:", value)
+		},
+		onSend: () => {
+			console.log("onSend clicked")
+		},
+	},
+} satisfies Meta<typeof STTSetupPopoverContent>
+
+export default meta
+type Story = StoryObj<typeof meta>
+
+export const FFmpegNotInstalled: Story = {
+	name: "FFmpeg not installed",
+	args: {
+		reason: "ffmpegNotInstalled",
+		setInputValue: (value: string) => {
+			console.log("setInputValue:", value)
+		},
+		onSend: () => {
+			console.log("onSend clicked")
+		},
+	},
+}
+
+export const OpenAIKeyMissing: Story = {
+	args: {
+		reason: "openaiKeyMissing",
+	},
+}
+
+export const BothMissing: Story = {}

+ 49 - 0
cli/CHANGELOG.md

@@ -1,5 +1,54 @@
 # @kilocode/cli
 
+## 0.19.3
+
+### Patch Changes
+
+- [#4827](https://github.com/Kilo-Org/kilocode/pull/4827) [`2a66afb`](https://github.com/Kilo-Org/kilocode/commit/2a66afb98b582a73d43b2147d941df32f3eb43a4) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix slash commands being intercepted by followup suggestions during `ask_followup_question` prompts.
+
+- [#4940](https://github.com/Kilo-Org/kilocode/pull/4940) [`9809864`](https://github.com/Kilo-Org/kilocode/commit/9809864ce51474c29b0db2635a19a92520a2f1f1) Thanks [@Drilmo](https://github.com/Drilmo)! - Add KILOCODE_DEV_CLI_PATH support for easier extension + CLI development workflow
+
+## 0.19.2
+
+### Patch Changes
+
+- [#4829](https://github.com/Kilo-Org/kilocode/pull/4829) [`4e09e36`](https://github.com/Kilo-Org/kilocode/commit/4e09e36bba165a2ab6f5e07f71a420faa49ea3ec) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix browser action results displaying raw base64 screenshot data as hexadecimal garbage
+
+## 0.19.1
+
+### Patch Changes
+
+- [#4810](https://github.com/Kilo-Org/kilocode/pull/4810) [`2d8f5b4`](https://github.com/Kilo-Org/kilocode/commit/2d8f5b4f823750d22701d962ba27885b01f78acb) Thanks [@kiloconnect](https://github.com/apps/kiloconnect)! - Add `--append-system-prompt` CLI option to append custom instructions to the system prompt
+
+## 0.19.0
+
+### Minor Changes
+
+- [#4730](https://github.com/Kilo-Org/kilocode/pull/4730) [`695f68f`](https://github.com/Kilo-Org/kilocode/commit/695f68f41e6b58e484d4ab914b568f5092ebdcfc) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Add autocomplete for `/mode` command in CLI, similar to model autocomplete. When typing `/mode ` and pressing tab, users now see suggestions for all available modes including default and custom modes with their names, descriptions, and source labels.
+
+### Patch Changes
+
+- [#4792](https://github.com/Kilo-Org/kilocode/pull/4792) [`25b7efe`](https://github.com/Kilo-Org/kilocode/commit/25b7efe9b4514e1e4ec7945dfcfcd34cc725f629) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix API request cost updates in the CLI when using static message rendering
+
+- [#4735](https://github.com/Kilo-Org/kilocode/pull/4735) [`ffabf05`](https://github.com/Kilo-Org/kilocode/commit/ffabf05c2684f36303610c97e6ca94d0ce0e48a9) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Add CLI `/condense` command for manual context condensation
+
+- [#4732](https://github.com/Kilo-Org/kilocode/pull/4732) [`2f16482`](https://github.com/Kilo-Org/kilocode/commit/2f16482b9fd84fb397a0ac6341edd9887d8b42e5) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Add instant ESC/Ctrl+X cancellation feedback with optimistic UI and reduced readline escape timeout
+
+- [#4740](https://github.com/Kilo-Org/kilocode/pull/4740) [`f291417`](https://github.com/Kilo-Org/kilocode/commit/f29141793f4c9340da139caaa62360daaef64e43) Thanks [@kiloconnect](https://github.com/apps/kiloconnect)! - Fix CLI formatting for unknown message types, JSON content, and codebase search results
+
+    - Improved JSON parsing in CI mode with proper error handling
+    - Enhanced unknown message type handling with JSON formatting
+    - Fixed codebase search results parsing to match extension payload format
+    - Fixed operator precedence bug in SayMessageRouter.tsx
+
+- [#4797](https://github.com/Kilo-Org/kilocode/pull/4797) [`ae3701b`](https://github.com/Kilo-Org/kilocode/commit/ae3701b85eb945c4ab5415690fca96226de3ad53) Thanks [@marius-kilocode](https://github.com/marius-kilocode)! - Fix slash command suggestions to select first entry by default when typing `/`
+
+- [#4778](https://github.com/Kilo-Org/kilocode/pull/4778) [`ea212ca`](https://github.com/Kilo-Org/kilocode/commit/ea212caa226234f8c126a3ffaa93d2696414dea3) Thanks [@kiloconnect](https://github.com/apps/kiloconnect)! - Fix CLI auto-update regression caused by inverted conditional logic with --nosplash flag. The version check now runs for all users by default, regardless of the nosplash flag state.
+
+- [#4780](https://github.com/Kilo-Org/kilocode/pull/4780) [`0cfe8b0`](https://github.com/Kilo-Org/kilocode/commit/0cfe8b0b9313b3016eaddfeb7ae1a247cd9b4011) Thanks [@Drilmo](https://github.com/Drilmo)! - Add log file rotation to prevent unbounded disk usage
+
+    The CLI log file at `~/.kilocode/cli/logs/cli.txt` now automatically rotates at startup when it exceeds 10 MB, keeping only the most recent ~5 MB of logs. This prevents the log file from growing indefinitely and consuming excessive disk space for heavy CLI users or long-running sessions.
+
 ## 0.18.1
 
 ### Patch Changes

+ 1 - 1
cli/README.md

@@ -245,7 +245,7 @@ To build and run the CLI locally off your branch:
 cd src
 pnpm bundle
 pnpm vsix
-pnpm vsix:unpackged
+pnpm vsix:unpacked
 cd ..
 ```
 

+ 35 - 4
cli/docs/DEVELOPMENT.md

@@ -6,13 +6,44 @@ We use `pnpm` for package management. Please make sure `pnpm` is installed.
 
 The CLI is currently built by bundling the extension core and replacing the vscode rendering parts with a cli rendering engine. To _develop_ on the CLI you need to follow a few steps:
 
-1. Build the extension core from the root workspace folder by running `pnpm cli:bundle`
+1. Install dependencies from the root workspace folder:
 
-2. Change into the cli folder `cd ./cli`
+    ```bash
+    pnpm install
+    ```
 
-3. Build & run the extension by running `pnpm start:dev`. If you want to use the CLI to work on its own code, you can run `pnpm start:dev -w ../` which will start it within the root workspace folder.
+2. Set up your environment file. Copy the sample and configure your API keys:
 
-4. While not required, it's pretty helpful to view log output of the cli in a separate terminal while you're developing. To do this, open a new terminal window and run `pnpm logs`. You can also run `pnpm logs:clear` to truncate any on-disk logs during development.
+    ```bash
+    cp .env.sample cli/dist/.env
+    # Edit cli/dist/.env with your API keys
+    ```
+
+3. Build the extension core from the root workspace folder:
+
+    ```bash
+    pnpm cli:bundle
+    ```
+
+4. Change into the cli folder:
+
+    ```bash
+    cd ./cli
+    ```
+
+5. Build & run the extension by running `pnpm start:dev`. If you want to use the CLI to work on its own code, you can run `pnpm start:dev -w ../` which will start it within the root workspace folder.
+
+6. While not required, it's pretty helpful to view log output of the cli in a separate terminal while you're developing. To do this, open a new terminal window and run `pnpm logs`. You can also run `pnpm logs:clear` to truncate any on-disk logs during development.
+
+### Quick Start (Testing Changes)
+
+If you just want to quickly test your changes without the dev server, you can run the bundled CLI directly:
+
+```bash
+# From the root workspace folder
+pnpm install && pnpm cli:bundle
+node cli/dist/index.js
+```
 
 ## Code Hygiene
 

+ 18 - 1
cli/esbuild.config.mjs

@@ -56,6 +56,23 @@ const afterBuildPlugin = {
 	},
 }
 
+// Problem matcher plugin for VS Code task integration
+const esbuildProblemMatcherPlugin = {
+	name: "esbuild-problem-matcher",
+	setup(build) {
+		build.onStart(() => console.log("[esbuild-problem-matcher#onStart]"))
+		build.onEnd((result) => {
+			result.errors.forEach(({ text, location }) => {
+				console.error(`✘ [ERROR] ${text}`)
+				if (location && location.file) {
+					console.error(`    ${location.file}:${location.line}:${location.column}:`)
+				}
+			})
+			console.log("[esbuild-problem-matcher#onEnd]")
+		})
+	},
+}
+
 const config = {
 	entryPoints: ["src/index.ts"],
 	bundle: true,
@@ -169,7 +186,7 @@ const __dirname = __dirname__(__filename);
 	minify: false,
 	treeShaking: true,
 	logLevel: "info",
-	plugins: [afterBuildPlugin],
+	plugins: [esbuildProblemMatcherPlugin, afterBuildPlugin],
 	alias: {
 		'is-in-ci': path.resolve(__dirname, 'src/patches/is-in-ci.ts'),
 	}

+ 1 - 1
cli/package.dist.json

@@ -1,6 +1,6 @@
 {
 	"name": "@kilocode/cli",
-	"version": "0.18.1",
+	"version": "0.19.3",
 	"description": "Terminal User Interface for Kilo Code",
 	"type": "module",
 	"main": "index.js",

+ 2 - 2
cli/package.json

@@ -1,6 +1,6 @@
 {
 	"name": "@kilocode/cli",
-	"version": "0.18.1",
+	"version": "0.19.3",
 	"description": "Terminal User Interface for Kilo Code",
 	"type": "module",
 	"main": "dist/index.js",
@@ -40,7 +40,7 @@
 		"@google/genai": "^1.0.0",
 		"@lmstudio/sdk": "^1.1.1",
 		"@mistralai/mistralai": "^1.9.18",
-		"@modelcontextprotocol/sdk": "^1.20.1",
+		"@modelcontextprotocol/sdk": "^1.24.0",
 		"@qdrant/js-client-rest": "^1.14.0",
 		"@roo-code/cloud": "workspace:^",
 		"@roo-code/telemetry": "workspace:^",

+ 109 - 0
cli/src/__tests__/append-system-prompt.test.ts

@@ -0,0 +1,109 @@
+import { describe, it, expect } from "vitest"
+import type { CLIOptions } from "../types/cli.js"
+
+describe("Append System Prompt CLI Option", () => {
+	describe("CLIOptions type", () => {
+		it("should accept appendSystemPrompt as a string option", () => {
+			const options: CLIOptions = {
+				mode: "code",
+				workspace: "/test/workspace",
+				appendSystemPrompt: "Custom instructions here",
+			}
+
+			expect(options.appendSystemPrompt).toBe("Custom instructions here")
+		})
+
+		it("should allow appendSystemPrompt to be undefined", () => {
+			const options: CLIOptions = {
+				mode: "code",
+				workspace: "/test/workspace",
+			}
+
+			expect(options.appendSystemPrompt).toBeUndefined()
+		})
+
+		it("should handle empty string for appendSystemPrompt", () => {
+			const options: CLIOptions = {
+				mode: "code",
+				workspace: "/test/workspace",
+				appendSystemPrompt: "",
+			}
+
+			expect(options.appendSystemPrompt).toBe("")
+		})
+
+		it("should handle multi-line appendSystemPrompt", () => {
+			const multiLinePrompt = `Line 1
+Line 2
+Line 3`
+			const options: CLIOptions = {
+				mode: "code",
+				workspace: "/test/workspace",
+				appendSystemPrompt: multiLinePrompt,
+			}
+
+			expect(options.appendSystemPrompt).toBe(multiLinePrompt)
+		})
+	})
+
+	describe("CLI flag parsing", () => {
+		it("should parse --append-system-prompt flag with value", () => {
+			// This test validates the expected behavior when the flag is parsed
+			const mockArgs = ["--append-system-prompt", "Custom instructions"]
+			const expectedValue = "Custom instructions"
+
+			// Simulate what commander.js would do
+			const parsedValue = mockArgs[1]
+			expect(parsedValue).toBe(expectedValue)
+		})
+
+		it("should handle --append-system-prompt with quoted multi-word value", () => {
+			const mockArgs = ["--append-system-prompt", "Always use TypeScript strict mode"]
+			const expectedValue = "Always use TypeScript strict mode"
+
+			const parsedValue = mockArgs[1]
+			expect(parsedValue).toBe(expectedValue)
+		})
+	})
+
+	describe("System prompt integration", () => {
+		it("should append custom text to system prompt when provided", () => {
+			const basePrompt = "You are Kilo Code, an AI assistant."
+			const appendText = "Always write tests first."
+			const expectedPrompt = `${basePrompt}
+
+${appendText}`
+
+			const result = `${basePrompt}\n\n${appendText}`
+			expect(result).toBe(expectedPrompt)
+		})
+
+		it("should not modify system prompt when appendSystemPrompt is undefined", () => {
+			const basePrompt = "You are Kilo Code, an AI assistant."
+			const appendText = undefined
+
+			const result = appendText ? `${basePrompt}\n\n${appendText}` : basePrompt
+			expect(result).toBe(basePrompt)
+		})
+
+		it("should not modify system prompt when appendSystemPrompt is empty string", () => {
+			const basePrompt = "You are Kilo Code, an AI assistant."
+			const appendText = ""
+
+			const result = appendText ? `${basePrompt}\n\n${appendText}` : basePrompt
+			expect(result).toBe(basePrompt)
+		})
+
+		it("should properly format appended text with newlines", () => {
+			const basePrompt = "You are Kilo Code."
+			const appendText = "Rule 1: Test first\nRule 2: Keep it simple"
+			const expectedPrompt = `You are Kilo Code.
+
+Rule 1: Test first
+Rule 2: Keep it simple`
+
+			const result = `${basePrompt}\n\n${appendText}`
+			expect(result).toBe(expectedPrompt)
+		})
+	})
+})

+ 14 - 18
cli/src/auth/__tests__/device-auth.test.ts

@@ -72,7 +72,7 @@ describe("Device Auth Flow", () => {
 			userEmail: "[email protected]",
 		}
 
-		global.fetch = vi.fn((url: string) => {
+		vi.spyOn(globalThis, "fetch").mockImplementation(((url: string) => {
 			if (url.includes("/api/device-auth/codes") && !url.match(/\/codes\/[^/]+$/)) {
 				return Promise.resolve({
 					ok: true,
@@ -87,7 +87,7 @@ describe("Device Auth Flow", () => {
 				} as Response)
 			}
 			return Promise.reject(new Error("Unexpected URL"))
-		}) as unknown as typeof fetch
+		}) as unknown as typeof fetch)
 
 		// Mock poll to immediately return success
 		vi.mocked(poll).mockResolvedValueOnce(mockPollResponse)
@@ -103,23 +103,19 @@ describe("Device Auth Flow", () => {
 	})
 
 	it("should handle initiation failure", async () => {
-		global.fetch = vi.fn(() =>
-			Promise.resolve({
-				ok: false,
-				status: 500,
-			} as Response),
-		) as unknown as typeof fetch
+		vi.spyOn(globalThis, "fetch").mockResolvedValue({
+			ok: false,
+			status: 500,
+		} as Response)
 
 		await expect(authenticateWithDeviceAuth()).rejects.toThrow("Failed to start authentication")
 	})
 
 	it("should handle rate limiting", async () => {
-		global.fetch = vi.fn(() =>
-			Promise.resolve({
-				ok: false,
-				status: 429,
-			} as Response),
-		) as unknown as typeof fetch
+		vi.spyOn(globalThis, "fetch").mockResolvedValue({
+			ok: false,
+			status: 429,
+		} as Response)
 
 		await expect(authenticateWithDeviceAuth()).rejects.toThrow(
 			"Too many pending authorization requests. Please try again later.",
@@ -133,7 +129,7 @@ describe("Device Auth Flow", () => {
 			expiresIn: 600,
 		}
 
-		global.fetch = vi.fn((url: string) => {
+		vi.spyOn(globalThis, "fetch").mockImplementation(((url: string) => {
 			if (url.includes("/api/device-auth/codes") && !url.match(/\/codes\/[^/]+$/)) {
 				return Promise.resolve({
 					ok: true,
@@ -148,7 +144,7 @@ describe("Device Auth Flow", () => {
 				} as Response)
 			}
 			return Promise.reject(new Error("Unexpected URL"))
-		}) as unknown as typeof fetch
+		}) as unknown as typeof fetch)
 
 		// Mock poll to immediately return the error
 		vi.mocked(poll).mockRejectedValueOnce(new Error("Authorization denied by user"))
@@ -163,7 +159,7 @@ describe("Device Auth Flow", () => {
 			expiresIn: 600,
 		}
 
-		global.fetch = vi.fn((url: string) => {
+		vi.spyOn(globalThis, "fetch").mockImplementation(((url: string) => {
 			if (url.includes("/api/device-auth/codes") && !url.match(/\/codes\/[^/]+$/)) {
 				return Promise.resolve({
 					ok: true,
@@ -178,7 +174,7 @@ describe("Device Auth Flow", () => {
 				} as Response)
 			}
 			return Promise.reject(new Error("Unexpected URL"))
-		}) as unknown as typeof fetch
+		}) as unknown as typeof fetch)
 
 		// Mock poll to immediately return the error
 		vi.mocked(poll).mockRejectedValueOnce(new Error("Authorization code expired"))

+ 4 - 0
cli/src/cli.ts

@@ -117,6 +117,10 @@ export class CLI {
 				serviceOptions.customModes = this.options.customModes
 			}
 
+			if (this.options.appendSystemPrompt) {
+				serviceOptions.appendSystemPrompt = this.options.appendSystemPrompt
+			}
+
 			this.service = createExtensionService(serviceOptions)
 			logs.debug("ExtensionService created with identity", "CLI", {
 				hasIdentity: !!identity,

+ 113 - 0
cli/src/commands/__tests__/condense.test.ts

@@ -0,0 +1,113 @@
+/**
+ * Tests for the /condense command
+ */
+
+import { describe, it, expect, beforeEach, vi } from "vitest"
+import { condenseCommand } from "../condense.js"
+import type { CommandContext } from "../core/types.js"
+import { createMockContext } from "./helpers/mockContext.js"
+
+describe("condenseCommand", () => {
+	let mockContext: CommandContext
+
+	beforeEach(() => {
+		// Create context with currentTask so condense can proceed
+		mockContext = createMockContext({
+			input: "/condense",
+			currentTask: {
+				id: "test-task-123",
+				ts: Date.now(),
+				task: "Test task",
+			},
+			chatMessages: [
+				{
+					ts: Date.now(),
+					type: "say",
+					say: "text",
+					text: "Hello, world!",
+				},
+			],
+		})
+	})
+
+	describe("command metadata", () => {
+		it("should have correct name", () => {
+			expect(condenseCommand.name).toBe("condense")
+		})
+
+		it("should have correct aliases", () => {
+			expect(condenseCommand.aliases).toEqual([])
+		})
+
+		it("should have correct category", () => {
+			expect(condenseCommand.category).toBe("chat")
+		})
+
+		it("should have correct priority", () => {
+			expect(condenseCommand.priority).toBe(6)
+		})
+
+		it("should have description", () => {
+			expect(condenseCommand.description).toBeTruthy()
+			expect(condenseCommand.description.toLowerCase()).toContain("condense")
+		})
+
+		it("should have usage examples", () => {
+			expect(condenseCommand.examples).toHaveLength(1)
+			expect(condenseCommand.examples).toContain("/condense")
+		})
+	})
+
+	describe("handler", () => {
+		it("should send condenseTaskContextRequest webview message", async () => {
+			await condenseCommand.handler(mockContext)
+
+			expect(mockContext.sendWebviewMessage).toHaveBeenCalledTimes(1)
+			expect(mockContext.sendWebviewMessage).toHaveBeenCalledWith({
+				type: "condenseTaskContextRequest",
+				text: "test-task-123",
+			})
+		})
+
+		it("should add system message before condensing", async () => {
+			await condenseCommand.handler(mockContext)
+
+			expect(mockContext.addMessage).toHaveBeenCalledTimes(1)
+			const addedMessage = (mockContext.addMessage as ReturnType<typeof vi.fn>).mock.calls[0][0]
+			expect(addedMessage.type).toBe("system")
+			expect(addedMessage.content).toContain("Condensing")
+		})
+
+		it("should execute without errors", async () => {
+			await expect(condenseCommand.handler(mockContext)).resolves.not.toThrow()
+		})
+
+		it("should NOT clear task state", async () => {
+			await condenseCommand.handler(mockContext)
+
+			expect(mockContext.clearTask).not.toHaveBeenCalled()
+		})
+
+		it("should NOT clear messages", async () => {
+			await condenseCommand.handler(mockContext)
+
+			expect(mockContext.clearMessages).not.toHaveBeenCalled()
+		})
+
+		it("should show error when no active task exists", async () => {
+			const emptyContext = createMockContext({
+				input: "/condense",
+				currentTask: null,
+				chatMessages: [],
+			})
+
+			await condenseCommand.handler(emptyContext)
+
+			expect(emptyContext.sendWebviewMessage).not.toHaveBeenCalled()
+			expect(emptyContext.addMessage).toHaveBeenCalledTimes(1)
+			const addedMessage = (emptyContext.addMessage as ReturnType<typeof vi.fn>).mock.calls[0][0]
+			expect(addedMessage.type).toBe("error")
+			expect(addedMessage.content).toContain("No active task")
+		})
+	})
+})

+ 2 - 0
cli/src/commands/__tests__/helpers/mockContext.ts

@@ -71,6 +71,8 @@ export function createMockContext(overrides: Partial<CommandContext> = {}): Comm
 		previousTaskHistoryPage: vi.fn().mockResolvedValue(null),
 		sendWebviewMessage: vi.fn().mockResolvedValue(undefined),
 		chatMessages: [],
+		// Current task context
+		currentTask: null,
 		modelListPageIndex: 0,
 		modelListFilters: {
 			sort: "preferred",

+ 43 - 0
cli/src/commands/condense.ts

@@ -0,0 +1,43 @@
+/**
+ * /condense command - Manually trigger context condensation
+ */
+
+import type { Command } from "./core/types.js"
+
+export const condenseCommand: Command = {
+	name: "condense",
+	aliases: [],
+	description: "Condense the conversation context to reduce token usage",
+	usage: "/condense",
+	examples: ["/condense"],
+	category: "chat",
+	priority: 6,
+	handler: async (context) => {
+		const { sendWebviewMessage, addMessage, currentTask } = context
+
+		const now = Date.now()
+
+		if (!currentTask) {
+			addMessage({
+				id: `condense-error-${now}`,
+				type: "error",
+				content: "No active task to condense. Start a conversation first.",
+				ts: now,
+			})
+			return
+		}
+
+		addMessage({
+			id: `condense-start-${now}`,
+			type: "system",
+			content: "Condensing conversation context...",
+			ts: now,
+		})
+
+		// Send request to extension with the task ID
+		await sendWebviewMessage({
+			type: "condenseTaskContextRequest",
+			text: currentTask.id,
+		})
+	},
+}

+ 3 - 0
cli/src/commands/core/types.ts

@@ -8,6 +8,7 @@ import type { CLIConfig, ProviderConfig } from "../../config/types.js"
 import type { ProfileData, BalanceData } from "../../state/atoms/profile.js"
 import type { TaskHistoryData, TaskHistoryFilters } from "../../state/atoms/taskHistory.js"
 import type { ModelListFilters } from "../../state/atoms/modelList.js"
+import type { HistoryItem } from "@roo-code/types"
 
 export interface Command {
 	name: string
@@ -77,6 +78,8 @@ export interface CommandContext {
 	sendWebviewMessage: (message: WebviewMessage) => Promise<void>
 	refreshTerminal: () => Promise<void>
 	chatMessages: ExtensionMessage[]
+	// Current task context
+	currentTask: HistoryItem | null
 	// Model list context
 	modelListPageIndex: number
 	modelListFilters: ModelListFilters

+ 2 - 0
cli/src/commands/index.ts

@@ -21,6 +21,7 @@ import { tasksCommand } from "./tasks.js"
 import { themeCommand } from "./theme.js"
 import { checkpointCommand } from "./checkpoint.js"
 import { sessionCommand } from "./session.js"
+import { condenseCommand } from "./condense.js"
 
 /**
  * Initialize all commands
@@ -41,4 +42,5 @@ export function initializeCommands(): void {
 	commandRegistry.register(themeCommand)
 	commandRegistry.register(checkpointCommand)
 	commandRegistry.register(sessionCommand)
+	commandRegistry.register(condenseCommand)
 }

+ 11 - 1
cli/src/config/__tests__/persistence-provider-merge.test.ts

@@ -1,9 +1,13 @@
 import { describe, it, expect, beforeEach, afterEach, vi } from "vitest"
 import * as fs from "fs/promises"
 import * as path from "path"
-import { loadConfig, setConfigPaths, resetConfigPaths } from "../persistence.js"
 import type { CLIConfig } from "../types.js"
 
+type PersistenceModule = typeof import("../persistence.js")
+let loadConfig: PersistenceModule["loadConfig"]
+let setConfigPaths: PersistenceModule["setConfigPaths"]
+let resetConfigPaths: PersistenceModule["resetConfigPaths"]
+
 // Mock the validation module
 vi.mock("../validation.js", () => ({
 	validateConfig: vi.fn().mockResolvedValue({ valid: true }),
@@ -14,6 +18,12 @@ describe("Provider Merging", () => {
 	const testFile = path.join(testDir, "config.json")
 
 	beforeEach(async () => {
+		// Some other test files mock `../persistence.js`; ensure we always test the real implementation here.
+		const persistence = await vi.importActual<PersistenceModule>("../persistence.js")
+		loadConfig = persistence.loadConfig
+		setConfigPaths = persistence.setConfigPaths
+		resetConfigPaths = persistence.resetConfigPaths
+
 		await fs.mkdir(testDir, { recursive: true })
 		setConfigPaths(testDir, testFile)
 	})

+ 17 - 0
cli/src/host/ExtensionHost.ts

@@ -11,6 +11,7 @@ export interface ExtensionHostOptions {
 	extensionRootPath: string // Root path for extension assets
 	identity?: IdentityInfo // Identity information for VSCode environment
 	customModes?: ModeConfig[] // Custom modes configuration
+	appendSystemPrompt?: string // Custom text to append to system prompt
 }
 
 // Extension module interface
@@ -786,6 +787,8 @@ export class ExtensionHost extends EventEmitter {
 				imageGeneration: false,
 				runSlashCommand: false,
 			},
+			// Add appendSystemPrompt from CLI options
+			...(this.options.appendSystemPrompt && { appendSystemPrompt: this.options.appendSystemPrompt }),
 		}
 
 		// The CLI will inject the actual configuration through updateState
@@ -1037,6 +1040,20 @@ export class ExtensionHost extends EventEmitter {
 				settings: Object.keys(autoApprovalSettings),
 			})
 		}
+
+		// Sync appendSystemPrompt to extension
+		// This setting is passed from CLI options and needs to be stored in the extension's
+		// contextProxy so it's available when generating the system prompt
+		const appendSystemPrompt = configState.appendSystemPrompt || this.options.appendSystemPrompt
+		if (appendSystemPrompt) {
+			await this.sendWebviewMessage({
+				type: "updateSettings",
+				updatedSettings: { appendSystemPrompt },
+			})
+			logs.debug("appendSystemPrompt synchronized to extension", "ExtensionHost", {
+				length: appendSystemPrompt.length,
+			})
+		}
 	}
 
 	/**

+ 5 - 0
cli/src/index.ts

@@ -19,6 +19,9 @@ import { getParallelModeParams } from "./parallel/parallel.js"
 import { DEBUG_MODES, DEBUG_FUNCTIONS } from "./debug/index.js"
 import { logs } from "./services/logs.js"
 
+// Log CLI location for debugging (visible in VS Code "Kilo-Code" output channel)
+logs.info(`CLI started from: ${import.meta.url}`)
+
 const program = new Command()
 let cli: CLI | null = null
 
@@ -48,6 +51,7 @@ program
 	.option("-s, --session <sessionId>", "Restore a session by ID")
 	.option("-f, --fork <shareId>", "Fork a session by ID")
 	.option("--nosplash", "Disable the welcome message and update notifications", false)
+	.option("--append-system-prompt <text>", "Append custom instructions to the system prompt")
 	.argument("[prompt]", "The prompt or command to execute")
 	.action(async (prompt, options) => {
 		// Validate that --existing-branch requires --parallel
@@ -228,6 +232,7 @@ program
 			session: options.session,
 			fork: options.fork,
 			noSplash: options.nosplash,
+			appendSystemPrompt: options.appendSystemPrompt,
 		})
 		await cli.start()
 		await cli.dispose()

+ 8 - 1
cli/src/services/extension.ts

@@ -22,6 +22,8 @@ export interface ExtensionServiceOptions {
 	extensionRootPath?: string
 	/** Identity information for VSCode environment */
 	identity?: IdentityInfo
+	/** Custom text to append to system prompt */
+	appendSystemPrompt?: string
 }
 
 /**
@@ -73,9 +75,10 @@ export interface ExtensionServiceEvents {
 export class ExtensionService extends EventEmitter {
 	private extensionHost: ExtensionHost
 	private messageBridge: MessageBridge
-	private options: Required<Omit<ExtensionServiceOptions, "identity" | "customModes">> & {
+	private options: Required<Omit<ExtensionServiceOptions, "identity" | "customModes" | "appendSystemPrompt">> & {
 		identity?: IdentityInfo
 		customModes?: ModeConfig[]
+		appendSystemPrompt?: string
 	}
 	private isInitialized = false
 	private isDisposed = false
@@ -95,6 +98,7 @@ export class ExtensionService extends EventEmitter {
 			extensionRootPath: options.extensionRootPath || extensionPaths.extensionRootPath,
 			...(options.identity && { identity: options.identity }),
 			...(options.customModes && { customModes: options.customModes }),
+			...(options.appendSystemPrompt && { appendSystemPrompt: options.appendSystemPrompt }),
 		}
 
 		// Create extension host
@@ -109,6 +113,9 @@ export class ExtensionService extends EventEmitter {
 		if (this.options.customModes) {
 			hostOptions.customModes = this.options.customModes
 		}
+		if (this.options.appendSystemPrompt) {
+			hostOptions.appendSystemPrompt = this.options.appendSystemPrompt
+		}
 		this.extensionHost = createExtensionHost(hostOptions)
 
 		// Create message bridge

+ 103 - 4
cli/src/services/logs.ts

@@ -1,5 +1,15 @@
-import { appendFileSync } from "fs"
-import * as fs from "fs-extra"
+import {
+	appendFileSync,
+	openSync,
+	readSync,
+	closeSync,
+	statSync,
+	writeFileSync,
+	renameSync,
+	unlinkSync,
+	mkdirSync,
+	existsSync,
+} from "fs"
 import * as path from "path"
 import { KiloCodePaths } from "../utils/paths.js"
 import { safeStringify } from "../utils/safe-stringify.js"
@@ -26,6 +36,11 @@ export interface LogFilter {
  */
 export class LogsService {
 	private static instance: LogsService | null = null
+
+	// Log rotation constants
+	private static readonly MAX_LOG_FILE_SIZE = 10 * 1024 * 1024 // 10 MB - rotate when file exceeds this size
+	private static readonly TRUNCATE_TO_SIZE = 5 * 1024 * 1024 // 5 MB - keep this much of the most recent logs
+
 	private logs: LogEntry[] = []
 	private maxEntries: number = 1000
 	private listeners: Array<(entry: LogEntry) => void> = []
@@ -173,7 +188,13 @@ export class LogsService {
 	private async initializeFileLogging(): Promise<void> {
 		try {
 			const logDir = path.dirname(this.logFilePath)
-			await fs.ensureDir(logDir)
+			// Create log directory if it doesn't exist (recursive)
+			if (!existsSync(logDir)) {
+				mkdirSync(logDir, { recursive: true })
+			}
+
+			// Rotate log file if needed (check size and truncate if too large)
+			this.rotateLogFileIfNeeded()
 		} catch (error) {
 			// Disable file logging if initialization fails
 			this.fileLoggingEnabled = false
@@ -184,6 +205,82 @@ export class LogsService {
 		}
 	}
 
+	/**
+	 * Rotate log file if it exceeds maximum size.
+	 * Keeps the most recent entries by truncating from the beginning.
+	 * This is called at startup to prevent unbounded log file growth.
+	 *
+	 * Uses byte-wise reading to avoid loading the entire file into memory,
+	 * and atomic write (temp file + rename) to prevent corruption on crash.
+	 * Uses only native fs module to avoid bundling issues with fs-extra.
+	 */
+	private rotateLogFileIfNeeded(): void {
+		let fd: number | null = null
+		let tempFilePath: string | null = null
+		try {
+			const stats = statSync(this.logFilePath)
+
+			if (stats.size <= LogsService.MAX_LOG_FILE_SIZE) {
+				return // File is within size limit, no rotation needed
+			}
+
+			// Calculate the start position to read from (keep only the last TRUNCATE_TO_SIZE bytes)
+			const startPosition = Math.max(0, stats.size - LogsService.TRUNCATE_TO_SIZE)
+			const bytesToRead = stats.size - startPosition
+
+			// Read only the bytes we need (byte-wise, no full file load)
+			fd = openSync(this.logFilePath, "r")
+			const buffer = Buffer.alloc(bytesToRead)
+			readSync(fd, buffer, 0, bytesToRead, startPosition)
+			closeSync(fd)
+			fd = null
+
+			// Convert to string and find the first complete line
+			let content = buffer.toString("utf8")
+			const firstNewline = content.indexOf("\n")
+			if (firstNewline > 0) {
+				content = content.slice(firstNewline + 1)
+			}
+
+			// Write to a temp file in the SAME directory (ensures same filesystem for atomic rename)
+			const logDir = path.dirname(this.logFilePath)
+			tempFilePath = path.join(logDir, `.cli.txt.rotate-${Date.now()}.tmp`)
+			writeFileSync(tempFilePath, content, "utf8")
+
+			// Atomic rename (works on same filesystem)
+			renameSync(tempFilePath, this.logFilePath)
+			tempFilePath = null // Successfully renamed, no cleanup needed
+		} catch (error: unknown) {
+			// Ensure fd is closed if an error occurred after opening
+			if (fd !== null) {
+				try {
+					closeSync(fd)
+				} catch {
+					// Ignore close errors
+				}
+			}
+
+			// Clean up temp file if it was created but rename failed
+			if (tempFilePath !== null) {
+				try {
+					unlinkSync(tempFilePath)
+				} catch {
+					// Ignore cleanup errors
+				}
+			}
+
+			// Handle ENOENT (file doesn't exist) silently - expected on first run
+			if (error instanceof Error && "code" in error && (error as NodeJS.ErrnoException).code === "ENOENT") {
+				return
+			}
+
+			// Warn about other errors (disk, permission, etc.) instead of silently ignoring
+			if (this.originalConsole) {
+				this.originalConsole.warn("[LogsService] Failed to rotate log file:", error)
+			}
+		}
+	}
+
 	/**
 	 * Format log entry for file output (same format as outputToConsole)
 	 */
@@ -228,7 +325,9 @@ export class LogsService {
 		try {
 			// Ensure directory exists before writing (synchronous to avoid race conditions)
 			const logDir = path.dirname(this.logFilePath)
-			fs.ensureDirSync(logDir)
+			if (!existsSync(logDir)) {
+				mkdirSync(logDir, { recursive: true })
+			}
 
 			const logLine = this.formatLogEntryForFile(entry) + "\n"
 			appendFileSync(this.logFilePath, logLine, "utf8")

+ 122 - 0
cli/src/state/atoms/__tests__/cancelling.test.ts

@@ -0,0 +1,122 @@
+/**
+ * Tests for isCancellingAtom - immediate feedback when user presses ESC to cancel
+ */
+
+import { describe, it, expect, vi, beforeEach } from "vitest"
+import { createStore } from "jotai"
+import { isCancellingAtom, isStreamingAtom } from "../ui.js"
+import { chatMessagesAtom } from "../extension.js"
+import { cancelTaskAtom } from "../actions.js"
+import { extensionServiceAtom, isServiceReadyAtom } from "../service.js"
+import type { ExtensionChatMessage } from "../../../types/messages.js"
+import type { ExtensionService } from "../../../services/extension.js"
+
+// Mock the extension service
+const mockSendWebviewMessage = vi.fn().mockResolvedValue(undefined)
+const mockExtensionService: Pick<ExtensionService, "sendWebviewMessage" | "isReady"> = {
+	sendWebviewMessage: mockSendWebviewMessage,
+	isReady: () => true,
+}
+
+describe("isCancellingAtom", () => {
+	let store: ReturnType<typeof createStore>
+
+	beforeEach(() => {
+		store = createStore()
+		vi.clearAllMocks()
+		// Set up mock extension service
+		store.set(extensionServiceAtom, mockExtensionService as ExtensionService)
+		store.set(isServiceReadyAtom, true)
+	})
+
+	describe("initial state", () => {
+		it("should be false by default", () => {
+			const isCancelling = store.get(isCancellingAtom)
+			expect(isCancelling).toBe(false)
+		})
+	})
+
+	describe("when cancelTaskAtom is triggered", () => {
+		it("should immediately set isCancellingAtom to true", async () => {
+			// Verify initial state
+			expect(store.get(isCancellingAtom)).toBe(false)
+
+			// Trigger cancel
+			await store.set(cancelTaskAtom)
+
+			// Should be true immediately
+			expect(store.get(isCancellingAtom)).toBe(true)
+		})
+
+		it("should send cancelTask message to extension", async () => {
+			await store.set(cancelTaskAtom)
+
+			expect(mockSendWebviewMessage).toHaveBeenCalledWith({
+				type: "cancelTask",
+			})
+		})
+	})
+
+	describe("reset behavior", () => {
+		it("should reset to false when streaming stops", () => {
+			// Set up streaming state with a partial message
+			const partialMessage: ExtensionChatMessage = {
+				type: "say",
+				say: "text",
+				ts: Date.now(),
+				text: "Processing...",
+				partial: true,
+			}
+			store.set(chatMessagesAtom, [partialMessage])
+
+			// Verify streaming is true
+			expect(store.get(isStreamingAtom)).toBe(true)
+
+			// Set cancelling to true
+			store.set(isCancellingAtom, true)
+			expect(store.get(isCancellingAtom)).toBe(true)
+
+			// Simulate streaming stopping (complete message)
+			const completeMessage: ExtensionChatMessage = {
+				type: "say",
+				say: "text",
+				ts: Date.now(),
+				text: "Done!",
+				partial: false,
+			}
+			store.set(chatMessagesAtom, [completeMessage])
+
+			// Verify streaming stopped
+			expect(store.get(isStreamingAtom)).toBe(false)
+
+			// Note: The actual reset logic will be implemented in an effect
+			// This test documents the expected behavior
+		})
+	})
+
+	describe("edge cases", () => {
+		it("should handle rapid ESC presses (already cancelling)", async () => {
+			// First cancel
+			await store.set(cancelTaskAtom)
+			expect(store.get(isCancellingAtom)).toBe(true)
+
+			// Second cancel while already cancelling
+			await store.set(cancelTaskAtom)
+			expect(store.get(isCancellingAtom)).toBe(true)
+
+			// Should still only have sent the message (idempotent behavior)
+			expect(mockSendWebviewMessage).toHaveBeenCalledTimes(2)
+		})
+
+		it("should not set cancelling when not streaming", async () => {
+			// No messages = not streaming
+			store.set(chatMessagesAtom, [])
+			expect(store.get(isStreamingAtom)).toBe(false)
+
+			// Cancel should still work (the keyboard handler checks streaming,
+			// but cancelTaskAtom itself doesn't need to)
+			await store.set(cancelTaskAtom)
+			expect(store.get(isCancellingAtom)).toBe(true)
+		})
+	})
+})

+ 328 - 0
cli/src/state/atoms/__tests__/default-selection.test.ts

@@ -0,0 +1,328 @@
+/**
+ * Tests for default selection behavior in dropdown menus
+ *
+ * This test file verifies that when dropdown menus appear (slash commands,
+ * argument suggestions, file mentions, approval menus), the first entry
+ * is selected by default.
+ */
+
+import { describe, it, expect, vi } from "vitest"
+import { createStore } from "jotai"
+import {
+	selectedIndexAtom,
+	suggestionsAtom,
+	argumentSuggestionsAtom,
+	fileMentionSuggestionsAtom,
+	setSuggestionsAtom,
+	setArgumentSuggestionsAtom,
+	setFileMentionSuggestionsAtom,
+	setFollowupSuggestionsAtom,
+	followupSuggestionsAtom,
+} from "../ui.js"
+import { setPendingApprovalAtom, pendingApprovalAtom, approvalOptionsAtom } from "../approval.js"
+import type { CommandSuggestion, ArgumentSuggestion, FileMentionSuggestion } from "../../../services/autocomplete.js"
+import type { Command } from "../../../commands/core/types.js"
+import type { ExtensionChatMessage } from "../../../types/messages.js"
+
+// Helper to create a mock command
+const createMockCommand = (name: string): Command => ({
+	name,
+	description: `${name} command`,
+	aliases: [],
+	usage: `/${name}`,
+	examples: [`/${name}`],
+	category: "test",
+	handler: vi.fn(),
+})
+
+// Helper to create a mock command suggestion
+const createCommandSuggestion = (name: string): CommandSuggestion => ({
+	command: createMockCommand(name),
+	matchScore: 90,
+	highlightedName: name,
+})
+
+// Helper to create a mock argument suggestion
+const createArgumentSuggestion = (value: string): ArgumentSuggestion => ({
+	value,
+	description: `${value} description`,
+	matchScore: 90,
+	highlightedValue: value,
+})
+
+// Helper to create a mock file mention suggestion
+const createFileMentionSuggestion = (path: string): FileMentionSuggestion => ({
+	value: path,
+	description: `in ${path.split("/").slice(0, -1).join("/")}`,
+	matchScore: 90,
+	highlightedValue: path,
+	type: "file",
+})
+
+// Helper to create a mock approval message
+const createApprovalMessage = (ask: string, text: string = "{}"): ExtensionChatMessage => ({
+	type: "ask",
+	ask,
+	text,
+	ts: Date.now(),
+	partial: false,
+	isAnswered: false,
+	say: "assistant",
+})
+
+describe("default selection behavior", () => {
+	describe("slash command suggestions", () => {
+		it("should set selectedIndex to 0 when command suggestions are set", () => {
+			const store = createStore()
+
+			// Initially, selectedIndex should be 0
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Set some command suggestions
+			const suggestions = [createCommandSuggestion("help"), createCommandSuggestion("mode")]
+
+			store.set(setSuggestionsAtom, suggestions)
+
+			// selectedIndex should be 0 (first entry selected)
+			expect(store.get(selectedIndexAtom)).toBe(0)
+			expect(store.get(suggestionsAtom)).toHaveLength(2)
+		})
+
+		it("should reset selectedIndex to -1 when command suggestions are cleared", () => {
+			const store = createStore()
+
+			// Set some suggestions first
+			store.set(setSuggestionsAtom, [createCommandSuggestion("help")])
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Navigate to a different index
+			store.set(selectedIndexAtom, 5)
+
+			// Clear suggestions - should reset selectedIndex to -1 (no selection)
+			store.set(setSuggestionsAtom, [])
+
+			// selectedIndex should be reset to -1
+			expect(store.get(selectedIndexAtom)).toBe(-1)
+		})
+
+		it("should reset selectedIndex to 0 when new suggestions replace old ones", () => {
+			const store = createStore()
+
+			// Set initial suggestions
+			store.set(setSuggestionsAtom, [createCommandSuggestion("help"), createCommandSuggestion("mode")])
+
+			// Manually change selectedIndex to simulate user navigation
+			store.set(selectedIndexAtom, 1)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+
+			// Set new suggestions
+			store.set(setSuggestionsAtom, [createCommandSuggestion("new"), createCommandSuggestion("task")])
+
+			// selectedIndex should be reset to 0
+			expect(store.get(selectedIndexAtom)).toBe(0)
+		})
+	})
+
+	describe("argument suggestions", () => {
+		it("should set selectedIndex to 0 when argument suggestions are set", () => {
+			const store = createStore()
+
+			// Set some argument suggestions
+			const suggestions = [createArgumentSuggestion("code"), createArgumentSuggestion("architect")]
+
+			store.set(setArgumentSuggestionsAtom, suggestions)
+
+			// selectedIndex should be 0 (first entry selected)
+			expect(store.get(selectedIndexAtom)).toBe(0)
+			expect(store.get(argumentSuggestionsAtom)).toHaveLength(2)
+		})
+
+		it("should reset selectedIndex to -1 when argument suggestions are cleared", () => {
+			const store = createStore()
+
+			// Set some suggestions first
+			store.set(setArgumentSuggestionsAtom, [createArgumentSuggestion("code")])
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Navigate to a different index
+			store.set(selectedIndexAtom, 5)
+
+			// Clear suggestions - should reset selectedIndex to -1 (no selection)
+			store.set(setArgumentSuggestionsAtom, [])
+
+			// selectedIndex should be reset to -1
+			expect(store.get(selectedIndexAtom)).toBe(-1)
+		})
+	})
+
+	describe("file mention suggestions", () => {
+		it("should set selectedIndex to 0 when file mention suggestions are set", () => {
+			const store = createStore()
+
+			// Set some file mention suggestions
+			const suggestions = [createFileMentionSuggestion("src/index.ts"), createFileMentionSuggestion("src/app.ts")]
+
+			store.set(setFileMentionSuggestionsAtom, suggestions)
+
+			// selectedIndex should be 0 (first entry selected)
+			expect(store.get(selectedIndexAtom)).toBe(0)
+			expect(store.get(fileMentionSuggestionsAtom)).toHaveLength(2)
+		})
+
+		it("should reset selectedIndex to -1 when file mention suggestions are cleared", () => {
+			const store = createStore()
+
+			// Set some suggestions first
+			store.set(setFileMentionSuggestionsAtom, [createFileMentionSuggestion("src/index.ts")])
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Navigate to a different index
+			store.set(selectedIndexAtom, 5)
+
+			// Clear suggestions - should reset selectedIndex to -1 (no selection)
+			store.set(setFileMentionSuggestionsAtom, [])
+
+			// selectedIndex should be reset to -1
+			expect(store.get(selectedIndexAtom)).toBe(-1)
+		})
+	})
+
+	describe("approval menu", () => {
+		it("should set selectedIndex to 0 when approval message is set", () => {
+			const store = createStore()
+
+			// Set an approval message
+			const message = createApprovalMessage("tool", JSON.stringify({ tool: "readFile" }))
+			store.set(setPendingApprovalAtom, message)
+
+			// selectedIndex should be 0 (first entry selected)
+			expect(store.get(selectedIndexAtom)).toBe(0)
+			expect(store.get(pendingApprovalAtom)).not.toBeNull()
+			expect(store.get(approvalOptionsAtom).length).toBeGreaterThan(0)
+		})
+
+		it("should reset selectedIndex to 0 when new approval message replaces old one", () => {
+			const store = createStore()
+
+			// Set initial approval message with explicit timestamp
+			const message1: ExtensionChatMessage = {
+				type: "ask",
+				ask: "tool",
+				text: JSON.stringify({ tool: "readFile" }),
+				ts: 1000, // Fixed timestamp
+				partial: false,
+				isAnswered: false,
+				say: "assistant",
+			}
+			store.set(setPendingApprovalAtom, message1)
+
+			// Manually change selectedIndex to simulate user navigation
+			store.set(selectedIndexAtom, 1)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+
+			// Set new approval message with different timestamp
+			const message2: ExtensionChatMessage = {
+				type: "ask",
+				ask: "command",
+				text: "git status",
+				ts: 2000, // Different timestamp
+				partial: false,
+				isAnswered: false,
+				say: "assistant",
+			}
+			store.set(setPendingApprovalAtom, message2)
+
+			// selectedIndex should be reset to 0
+			expect(store.get(selectedIndexAtom)).toBe(0)
+		})
+
+		it("should NOT reset selectedIndex for command_output updates (streaming)", () => {
+			const store = createStore()
+
+			// Set initial command_output message
+			const message1: ExtensionChatMessage = {
+				type: "ask",
+				ask: "command_output",
+				text: "Initial output",
+				ts: 12345, // Fixed timestamp
+				partial: true,
+				isAnswered: false,
+				say: "assistant",
+			}
+			store.set(setPendingApprovalAtom, message1)
+
+			// Manually change selectedIndex to simulate user navigation
+			store.set(selectedIndexAtom, 1)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+
+			// Update the same message (same timestamp, different content)
+			const message2: ExtensionChatMessage = {
+				...message1,
+				text: "Updated output",
+				partial: false,
+			}
+			store.set(setPendingApprovalAtom, message2)
+
+			// selectedIndex should NOT be reset (same message, just updated)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+		})
+	})
+
+	describe("followup suggestions", () => {
+		it("should set selectedIndex to -1 when followup suggestions are set (by design)", () => {
+			const store = createStore()
+
+			// Set some followup suggestions
+			const suggestions = [{ answer: "Yes, continue" }, { answer: "No, stop" }]
+
+			store.set(setFollowupSuggestionsAtom, suggestions)
+
+			// selectedIndex should be -1 (no selection by design - allows custom typing)
+			expect(store.get(selectedIndexAtom)).toBe(-1)
+			expect(store.get(followupSuggestionsAtom)).toHaveLength(2)
+		})
+	})
+
+	describe("cross-menu selection isolation", () => {
+		it("should reset selection when switching from commands to arguments", () => {
+			const store = createStore()
+
+			// Set command suggestions
+			store.set(setSuggestionsAtom, [createCommandSuggestion("help"), createCommandSuggestion("mode")])
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Navigate to second item
+			store.set(selectedIndexAtom, 1)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+
+			// Clear commands and set arguments
+			store.set(setSuggestionsAtom, [])
+			store.set(setArgumentSuggestionsAtom, [createArgumentSuggestion("code"), createArgumentSuggestion("ask")])
+
+			// selectedIndex should be 0 for the new argument suggestions
+			expect(store.get(selectedIndexAtom)).toBe(0)
+		})
+
+		it("should reset selection when switching from arguments to file mentions", () => {
+			const store = createStore()
+
+			// Set argument suggestions
+			store.set(setArgumentSuggestionsAtom, [createArgumentSuggestion("code"), createArgumentSuggestion("ask")])
+			expect(store.get(selectedIndexAtom)).toBe(0)
+
+			// Navigate to second item
+			store.set(selectedIndexAtom, 1)
+			expect(store.get(selectedIndexAtom)).toBe(1)
+
+			// Clear arguments and set file mentions
+			store.set(setArgumentSuggestionsAtom, [])
+			store.set(setFileMentionSuggestionsAtom, [
+				createFileMentionSuggestion("src/index.ts"),
+				createFileMentionSuggestion("src/app.ts"),
+			])
+
+			// selectedIndex should be 0 for the new file mention suggestions
+			expect(store.get(selectedIndexAtom)).toBe(0)
+		})
+	})
+})

+ 28 - 0
cli/src/state/atoms/__tests__/extension-message-updates.test.ts

@@ -177,6 +177,34 @@ describe("updateChatMessageByTsAtom", () => {
 		expect(messages[0]?.text).toBe("This is a long message")
 	})
 
+	it("should update non-partial messages when content changes but length stays the same", () => {
+		// Setup: Add initial message and initialize version tracking
+		const initialMessage: ExtensionChatMessage = {
+			ts: 1000,
+			type: "say",
+			say: "api_req_started",
+			text: '{"cost":0.0010}',
+			partial: false,
+		}
+		store.set(updateChatMessagesAtom, [initialMessage])
+		store.set(updateChatMessageByTsAtom, initialMessage)
+
+		// Update with different content but identical length (cost changed, same number of digits)
+		const updatedMessage: ExtensionChatMessage = {
+			ts: 1000,
+			type: "say",
+			say: "api_req_started",
+			text: '{"cost":0.0020}',
+			partial: false,
+		}
+		expect(updatedMessage.text?.length).toBe(initialMessage.text?.length)
+		store.set(updateChatMessageByTsAtom, updatedMessage)
+
+		const messages = store.get(chatMessagesAtom)
+		expect(messages).toHaveLength(1)
+		expect(messages[0]?.text).toBe('{"cost":0.0020}')
+	})
+
 	it("should handle ask messages correctly", () => {
 		// Setup: Add partial ask message
 		const partialAsk: ExtensionChatMessage = {

+ 102 - 0
cli/src/state/atoms/__tests__/keyboard.test.ts

@@ -7,6 +7,8 @@ import {
 	argumentSuggestionsAtom,
 	selectedIndexAtom,
 	fileMentionSuggestionsAtom,
+	setFollowupSuggestionsAtom,
+	followupSuggestionsAtom,
 } from "../ui.js"
 import { textBufferStringAtom, textBufferStateAtom } from "../textBuffer.js"
 import {
@@ -1151,4 +1153,104 @@ describe("keypress atoms", () => {
 			expect(store.get(exitPromptVisibleAtom)).toBe(true)
 		})
 	})
+
+	describe("followup suggestions vs slash command input", () => {
+		it("should submit typed /command (not followup suggestion) when input starts with '/'", async () => {
+			const mockCallback = vi.fn()
+			store.set(submissionCallbackAtom, { callback: mockCallback })
+
+			// Followup suggestions are active (ask_followup_question), which normally takes priority over autocomplete.
+			store.set(setFollowupSuggestionsAtom, [{ answer: "Yes, continue" }, { answer: "No, stop" }])
+
+			// Type a slash command.
+			for (const char of ["/", "h", "e", "l", "p"]) {
+				const key: Key = {
+					name: char,
+					sequence: char,
+					ctrl: false,
+					meta: false,
+					shift: false,
+					paste: false,
+				}
+				store.set(keyboardHandlerAtom, key)
+			}
+
+			// Simulate the "auto-select first item" behavior from autocomplete that can set selectedIndex to 0.
+			// In the buggy behavior, followup mode is still active and this causes Enter to submit the followup suggestion instead.
+			store.set(selectedIndexAtom, 0)
+
+			// Press Enter to submit.
+			const enterKey: Key = {
+				name: "return",
+				sequence: "\r",
+				ctrl: false,
+				meta: false,
+				shift: false,
+				paste: false,
+			}
+			await store.set(keyboardHandlerAtom, enterKey)
+
+			// Wait for async operations to complete
+			await new Promise((resolve) => setTimeout(resolve, 10))
+
+			expect(mockCallback).toHaveBeenCalledWith("/help")
+			// Followup should remain active after running a slash command.
+			expect(store.get(followupSuggestionsAtom)).toHaveLength(2)
+			// Followup should not auto-select after command execution.
+			expect(store.get(selectedIndexAtom)).toBe(-1)
+		})
+
+		it("should dismiss followup suggestions for /clear and /new commands", async () => {
+			const mockCallback = vi.fn()
+			store.set(submissionCallbackAtom, { callback: mockCallback })
+
+			store.set(setFollowupSuggestionsAtom, [{ answer: "Yes, continue" }, { answer: "No, stop" }])
+
+			// Type /clear
+			for (const char of ["/", "c", "l", "e", "a", "r"]) {
+				const key: Key = {
+					name: char,
+					sequence: char,
+					ctrl: false,
+					meta: false,
+					shift: false,
+					paste: false,
+				}
+				store.set(keyboardHandlerAtom, key)
+			}
+
+			const enterKey: Key = {
+				name: "return",
+				sequence: "\r",
+				ctrl: false,
+				meta: false,
+				shift: false,
+				paste: false,
+			}
+			await store.set(keyboardHandlerAtom, enterKey)
+			await new Promise((resolve) => setTimeout(resolve, 10))
+
+			expect(mockCallback).toHaveBeenCalledWith("/clear")
+			expect(store.get(followupSuggestionsAtom)).toHaveLength(0)
+
+			// Re-seed followup and type /new
+			store.set(setFollowupSuggestionsAtom, [{ answer: "Yes, continue" }, { answer: "No, stop" }])
+			for (const char of ["/", "n", "e", "w"]) {
+				const key: Key = {
+					name: char,
+					sequence: char,
+					ctrl: false,
+					meta: false,
+					shift: false,
+					paste: false,
+				}
+				store.set(keyboardHandlerAtom, key)
+			}
+			await store.set(keyboardHandlerAtom, enterKey)
+			await new Promise((resolve) => setTimeout(resolve, 10))
+
+			expect(mockCallback).toHaveBeenCalledWith("/new")
+			expect(store.get(followupSuggestionsAtom)).toHaveLength(0)
+		})
+	})
 })

Some files were not shown because too many files changed in this diff