mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-19 01:51:21 +08:00
Merge branch 'main' into christiaan/reasoning
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
name: Check Links
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, dev]
|
||||
pull_request:
|
||||
schedule:
|
||||
# Run daily at 9am UTC
|
||||
- cron: "0 9 * * *"
|
||||
workflow_dispatch: # Allow manual trigger
|
||||
|
||||
jobs:
|
||||
link-checker:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Link Checker
|
||||
uses: lycheeverse/lychee-action@v2
|
||||
with:
|
||||
args: "**/*.md"
|
||||
workingDirectory: packages/kilo-docs
|
||||
fail: true
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# Contributing to Kilo CLI
|
||||
|
||||
See [the Documentation for details on contributing](https://kilo.ai/docs/extending/contributing-to-kilo).
|
||||
See [the Documentation for details on contributing](https://kilo.ai/docs/contributing).
|
||||
|
||||
## TL;DR
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
},
|
||||
"packages/app": {
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@kilocode/kilo-i18n": "workspace:*",
|
||||
"@kilocode/kilo-ui": "workspace:*",
|
||||
@@ -75,7 +75,7 @@
|
||||
},
|
||||
"packages/desktop": {
|
||||
"name": "@opencode-ai/desktop",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@opencode-ai/app": "workspace:*",
|
||||
"@opencode-ai/ui": "workspace:*",
|
||||
@@ -108,7 +108,7 @@
|
||||
},
|
||||
"packages/kilo-docs": {
|
||||
"name": "@kilocode/kilo-docs",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@docsearch/css": "^4",
|
||||
"@docsearch/js": "^4",
|
||||
@@ -136,7 +136,7 @@
|
||||
},
|
||||
"packages/kilo-gateway": {
|
||||
"name": "@kilocode/kilo-gateway",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@clack/prompts": "1.0.0-alpha.1",
|
||||
"@kilocode/plugin": "workspace:*",
|
||||
@@ -168,7 +168,7 @@
|
||||
},
|
||||
"packages/kilo-i18n": {
|
||||
"name": "@kilocode/kilo-i18n",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"devDependencies": {
|
||||
"@tsconfig/node22": "catalog:",
|
||||
"@types/bun": "catalog:",
|
||||
@@ -178,7 +178,7 @@
|
||||
},
|
||||
"packages/kilo-telemetry": {
|
||||
"name": "@kilocode/kilo-telemetry",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@kilocode/kilo-gateway": "workspace:*",
|
||||
"@opentelemetry/api": "1.9.0",
|
||||
@@ -198,7 +198,7 @@
|
||||
},
|
||||
"packages/kilo-ui": {
|
||||
"name": "@kilocode/kilo-ui",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@kobalte/core": "0.13.11",
|
||||
},
|
||||
@@ -221,7 +221,7 @@
|
||||
},
|
||||
"packages/kilo-vscode": {
|
||||
"name": "kilo-code",
|
||||
"version": "7.0.24",
|
||||
"version": "7.0.25",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "^0.39.0",
|
||||
"@kilocode/kilo-i18n": "workspace:*",
|
||||
@@ -265,7 +265,7 @@
|
||||
},
|
||||
"packages/opencode": {
|
||||
"name": "@kilocode/cli",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"bin": {
|
||||
"kilo": "./bin/kilo",
|
||||
"kilocode": "./bin/kilocode",
|
||||
@@ -375,7 +375,7 @@
|
||||
},
|
||||
"packages/plugin": {
|
||||
"name": "@kilocode/plugin",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@kilocode/sdk": "workspace:*",
|
||||
"zod": "catalog:",
|
||||
@@ -389,14 +389,14 @@
|
||||
},
|
||||
"packages/script": {
|
||||
"name": "@opencode-ai/script",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"devDependencies": {
|
||||
"@types/bun": "catalog:",
|
||||
},
|
||||
},
|
||||
"packages/sdk/js": {
|
||||
"name": "@kilocode/sdk",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"devDependencies": {
|
||||
"@hey-api/openapi-ts": "0.90.10",
|
||||
"@tsconfig/node22": "catalog:",
|
||||
@@ -407,7 +407,7 @@
|
||||
},
|
||||
"packages/ui": {
|
||||
"name": "@opencode-ai/ui",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"@kilocode/sdk": "workspace:*",
|
||||
"@kobalte/core": "catalog:",
|
||||
@@ -449,7 +449,7 @@
|
||||
},
|
||||
"packages/util": {
|
||||
"name": "@opencode-ai/util",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {
|
||||
"zod": "catalog:",
|
||||
},
|
||||
|
||||
+1
-1
@@ -102,6 +102,6 @@
|
||||
"@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch",
|
||||
"ghostty-web@0.3.0": "patches/ghostty-web@0.3.0.patch"
|
||||
},
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"peerDependencies": {}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ import { test, expect } from "../fixtures"
|
||||
import { promptSelector } from "../selectors"
|
||||
import { closeDialog, openSettings, clickListItem } from "../actions"
|
||||
|
||||
test("hiding a model removes it from the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change start
|
||||
test.skip("hiding a model removes it from the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change end
|
||||
await gotoSession()
|
||||
|
||||
await page.locator(promptSelector).click()
|
||||
|
||||
@@ -2,7 +2,9 @@ import { test, expect } from "../fixtures"
|
||||
import { promptSelector } from "../selectors"
|
||||
import { closeDialog, openSettings } from "../actions"
|
||||
|
||||
test("hiding a model removes it from the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change start
|
||||
test.skip("hiding a model removes it from the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change end
|
||||
await gotoSession()
|
||||
|
||||
await page.locator(promptSelector).click()
|
||||
@@ -60,7 +62,9 @@ test("hiding a model removes it from the model picker", async ({ page, gotoSessi
|
||||
await expect(pickerAgain).toHaveCount(0)
|
||||
})
|
||||
|
||||
test("showing a hidden model restores it to the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change start
|
||||
test.skip("showing a hidden model restores it to the model picker", async ({ page, gotoSession }) => {
|
||||
// kilocode_change end
|
||||
await gotoSession()
|
||||
|
||||
await page.locator(promptSelector).click()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@opencode-ai/app",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"description": "",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@opencode-ai/desktop",
|
||||
"private": true,
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
id = "kilo"
|
||||
name = "Kilo"
|
||||
description = "The open source coding agent."
|
||||
version = "1.0.24"
|
||||
version = "1.0.25"
|
||||
schema_version = 1
|
||||
authors = ["Anomaly"]
|
||||
repository = "https://github.com/Kilo-Org/kilo"
|
||||
@@ -11,26 +11,26 @@ name = "Kilo"
|
||||
icon = "./icons/opencode.svg"
|
||||
|
||||
[agent_servers.opencode.targets.darwin-aarch64]
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.24/opencode-darwin-arm64.zip"
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.25/opencode-darwin-arm64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.darwin-x86_64]
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.24/opencode-darwin-x64.zip"
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.25/opencode-darwin-x64.zip"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.linux-aarch64]
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.24/opencode-linux-arm64.tar.gz"
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.25/opencode-linux-arm64.tar.gz"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.linux-x86_64]
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.24/opencode-linux-x64.tar.gz"
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.25/opencode-linux-x64.tar.gz"
|
||||
cmd = "./opencode"
|
||||
args = ["acp"]
|
||||
|
||||
[agent_servers.opencode.targets.windows-x86_64]
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.24/opencode-windows-x64.zip"
|
||||
archive = "https://github.com/Kilo-Org/kilo/releases/download/v1.0.25/opencode-windows-x64.zip"
|
||||
cmd = "./opencode.exe"
|
||||
args = ["acp"]
|
||||
|
||||
@@ -8,4 +8,5 @@ screenshots/
|
||||
.beads/
|
||||
.env
|
||||
next-env.d.ts
|
||||
tsconfig.tsbuildinfo
|
||||
tsconfig.tsbuildinfo
|
||||
lycheeout.*
|
||||
@@ -1,55 +0,0 @@
|
||||
# Full Next.js example
|
||||
|
||||
This is a full-featured boilerplate for a creating a documentation website using Markdoc and Next.js.
|
||||
|
||||
<img width="2032" alt="image" src="https://user-images.githubusercontent.com/62121649/174916143-16f18270-0463-402c-8b48-33c627ea7a7e.png">
|
||||
|
||||
## Setup
|
||||
|
||||
First, clone this repo and install the dependencies required:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
# or
|
||||
yarn install
|
||||
```
|
||||
|
||||
Then, run the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
# or
|
||||
yarn dev
|
||||
```
|
||||
|
||||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
||||
|
||||
You can start editing the page by modifying `index.md`. The page auto-updates as you edit the file.
|
||||
|
||||
## Deploy
|
||||
|
||||
The quickest way to deploy your own version of this boilerplate is by deploying it with [Vercel](https://vercel.com) or [Netlify](https://www.netlify.com/) by clicking one of the buttons below.
|
||||
|
||||
### Deploy with Vercel
|
||||
|
||||
[](https://vercel.com/new/clone?repository-url=https://github.com/markdoc/next.js-starter)
|
||||
|
||||
### Deploy to Netlify
|
||||
|
||||
[](https://app.netlify.com/start/deploy?repository=https://github.com/markdoc/next.js-starter)
|
||||
|
||||
## Contributing
|
||||
|
||||
When making documentation _only_ changes, use branch names prefixed with `docs/`:
|
||||
|
||||
```bash
|
||||
git checkout -b docs/your-change-description
|
||||
```
|
||||
|
||||
Examples:
|
||||
|
||||
- `docs/add-mcp-tutorial`
|
||||
- `docs/fix-installation-steps`
|
||||
- `docs/update-api-reference`
|
||||
|
||||
For full contribution guidelines, see the [Contributing Guide](https://kilo.ai/docs/contributing).
|
||||
@@ -337,7 +337,7 @@ export function TopNav({ onMobileMenuToggle, isMobileMenuOpen = false, showMobil
|
||||
<p>
|
||||
We're <Link href="https://blog.kilo.ai/p/kilo-cli">replatforming our extensions on the new Kilo CLI</Link>.
|
||||
Contribute to the new CLI and pre-release extensions at{" "}
|
||||
<Link href="https://github.com/Kilo-Org/kilo">Kilo-Org/kilo</Link>.
|
||||
<Link href="https://github.com/Kilo-Org/kilocode">Kilo-Org/kilocode</Link>.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -34,10 +34,6 @@ export const ContributingNav: NavSection[] = [
|
||||
href: "/contributing/architecture/agent-observability",
|
||||
children: "Agent Observability",
|
||||
},
|
||||
{
|
||||
href: "/contributing/architecture/annual-billing",
|
||||
children: "Annual Billing",
|
||||
},
|
||||
{
|
||||
href: "/contributing/architecture/benchmarking",
|
||||
children: "Benchmarking",
|
||||
|
||||
@@ -41,7 +41,6 @@ export const CustomizeNav: NavSection[] = [
|
||||
href: "/customize/context/kilocodeignore",
|
||||
children: ".kilocodeignore",
|
||||
},
|
||||
{ href: "/customize/context/memory-bank", children: "Memory Bank" },
|
||||
{
|
||||
href: "/customize/context/large-projects",
|
||||
children: "Large Projects",
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
root_dir = "."
|
||||
fallback_extensions = ["md"]
|
||||
remap = ["kilo-docs/docs kilo-docs/pages"]
|
||||
|
||||
format = "detailed"
|
||||
max_redirects = 2
|
||||
exclude_path = ["node_modules"]
|
||||
|
||||
accept = [
|
||||
"200",
|
||||
"403",
|
||||
"429",
|
||||
"301",
|
||||
"307",
|
||||
]
|
||||
|
||||
exclude = [
|
||||
'\.png$',
|
||||
'https://synthetic.new/user-settings/api',
|
||||
'https://platform.slack-edge.com/img/add_to_slack.png',
|
||||
'https://console.groq.com/pages/models',
|
||||
'https://glama.ai/settings/gateway/api-keys',
|
||||
'^https?://(api|console)\.mistral\.ai',
|
||||
'^https?://(app|console)\.requesty\.ai',
|
||||
'^https?://(cloud|console)\.google\.ai',
|
||||
'https://opencode.ai/pages/config',
|
||||
'^localhost:3000/'
|
||||
]
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kilocode/kilo-docs",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev --webpack --port 3002",
|
||||
|
||||
@@ -73,7 +73,7 @@ export default function MyApp({ Component, pageProps }: AppProps<MyAppProps>) {
|
||||
posthog.capture("$pageview")
|
||||
}, [])
|
||||
|
||||
// Close mobile menu on route change and track pageviews
|
||||
// Close mobile menu on route change, track pageviews, and reset scroll position
|
||||
useEffect(() => {
|
||||
const handleRouteChange = () => {
|
||||
setIsMobileMenuOpen(false)
|
||||
@@ -81,6 +81,11 @@ export default function MyApp({ Component, pageProps }: AppProps<MyAppProps>) {
|
||||
|
||||
const handleRouteComplete = () => {
|
||||
posthog.capture("$pageview")
|
||||
// Reset scroll position of the main content container on navigation
|
||||
const mainContent = document.querySelector(".main-content")
|
||||
if (mainContent) {
|
||||
mainContent.scrollTop = 0
|
||||
}
|
||||
}
|
||||
|
||||
router.events.on("routeChangeStart", handleRouteChange)
|
||||
@@ -175,7 +180,7 @@ export default function MyApp({ Component, pageProps }: AppProps<MyAppProps>) {
|
||||
<div className="article-content flex column mt-5">
|
||||
<Component {...pageProps} />
|
||||
</div>
|
||||
<div className="right-sidebar">
|
||||
<div className="right-sidebar" key={router.asPath}>
|
||||
{markdoc && <CopyPageButton />}
|
||||
<TableOfContents toc={toc} />
|
||||
</div>
|
||||
|
||||
@@ -25,4 +25,4 @@ Kilo Code supports Google's Gemini family of models through the Google AI Gemini
|
||||
## Tips and Notes
|
||||
|
||||
- **Pricing:** Gemini API usage is priced based on input and output tokens. Refer to the [Gemini pricing page](https://ai.google.dev/pricing) for detailed information.
|
||||
- **Codebase Indexing:** The `gemini-embedding-001` model is specifically supported for [codebase indexing](/docs/features/codebase-indexing), providing high-quality embeddings for semantic code search.
|
||||
- **Codebase Indexing:** The `gemini-embedding-001` model is specifically supported for [codebase indexing](/docs/customize/context/codebase-indexing), providing high-quality embeddings for semantic code search.
|
||||
|
||||
@@ -70,4 +70,4 @@ With the Kilo Code provider, if you sign up with Google you can also connect oth
|
||||
- **Latest Models:** Automatic access to the most current frontier coding models
|
||||
- **Support Available:** Contact [hi@kilo.ai](mailto:hi@kilo.ai) for questions about pricing or tokens
|
||||
|
||||
For detailed setup instructions, see [Setting up Kilo Code](/docs/getting-started/setting-up).
|
||||
For detailed setup instructions, see [Setting up Kilo Code](/docs/getting-started/setup-authentication).
|
||||
|
||||
@@ -27,4 +27,3 @@ MiniMax is a global AI foundation model company focused on fast, cost-efficient
|
||||
- **Performance:** MiniMax M2.1 emphasizes fast inference, strong coding ability, and exceptional tool-calling performance.
|
||||
- **Context Window:** MiniMax models support ultra-long context windows suitable for large codebases and agent workflows.
|
||||
- **Pricing:** Pricing varies by model, with input costs ranging from $0.20 to $0.30 per million tokens and output costs from $1.10 to $2.20 per million tokens. Refer to the MiniMax documentation for the most current pricing information.
|
||||
- **MiniMax M2.1** is currently available for free exclusively for [Kilo for Slack](/docs/slack).
|
||||
|
||||
@@ -4,7 +4,7 @@ sidebar_label: VS Code Language Model API
|
||||
|
||||
# Using VS Code Language Model API With Kilo Code
|
||||
|
||||
Kilo Code includes _experimental_ support for the [VS Code Language Model API](https://code.visualstudio.com/api/language-extensions/language-model-access). This API allows extensions to provide access to language models directly within VS Code. This means you can potentially use models from:
|
||||
Kilo Code includes _experimental_ support for the [VS Code Language Model API](https://code.visualstudio.com/docs/copilot/customization/language-models). This API allows extensions to provide access to language models directly within VS Code. This means you can potentially use models from:
|
||||
|
||||
- **GitHub Copilot:** If you have a Copilot subscription and the extension installed.
|
||||
- **Other VS Code Extensions:** Any extension that implements the Language Model API.
|
||||
|
||||
@@ -194,4 +194,4 @@ For additional support:
|
||||
|
||||
- Visit the [ZenMux documentation](https://zenmux.ai/docs)
|
||||
- Contact ZenMux support through their dashboard
|
||||
- Check the [Kilo Code GitHub repository](https://github.com/kilocode/kilocode) for integration-specific issues
|
||||
- Check the [Kilo Code GitHub repository](https://github.com/Kilo-Org/kilocode) for integration-specific issues
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import type { NextApiRequest, NextApiResponse } from "next"
|
||||
import fs from "fs"
|
||||
import path from "path"
|
||||
import { Nav } from "../../lib/nav"
|
||||
import type { NavLink, NavSection } from "../../lib/types"
|
||||
|
||||
/**
|
||||
* Recursively finds all markdown files in a directory
|
||||
@@ -37,6 +39,51 @@ function filePathToUrlPath(filePath: string, pagesDir: string): string {
|
||||
return "/" + relativePath
|
||||
}
|
||||
|
||||
function extractFrontmatterTitle(content: string): string | null {
|
||||
const match = content.match(/^---\n[\s\S]*?^title:\s*"?([^"\n]+)"?\s*$[\s\S]*?^---\n/m)
|
||||
if (!match) return null
|
||||
return match[1]?.trim() || null
|
||||
}
|
||||
|
||||
function buildTitleMap(markdownFiles: string[], pagesDir: string) {
|
||||
const map = new Map<string, string>()
|
||||
|
||||
for (const filePath of markdownFiles) {
|
||||
const urlPath = filePathToUrlPath(filePath, pagesDir)
|
||||
const content = fs.readFileSync(filePath, "utf-8")
|
||||
const title = extractFrontmatterTitle(content)
|
||||
if (title) {
|
||||
map.set(urlPath, title)
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
function addNavLink(items: string[], link: NavLink, baseUrl: string, depth: number, titleMap: Map<string, string>) {
|
||||
const indent = " ".repeat(depth)
|
||||
const rawUrl = `${baseUrl}/api/raw-markdown?path=${encodeURIComponent(link.href)}`
|
||||
const title = titleMap.get(link.href) || link.children
|
||||
items.push(`${indent}- [${title}](${rawUrl})`)
|
||||
|
||||
if (link.subLinks) {
|
||||
for (const subLink of link.subLinks) {
|
||||
addNavLink(items, subLink, baseUrl, depth + 1, titleMap)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function addNavSection(items: string[], section: NavSection, baseUrl: string, titleMap: Map<string, string>) {
|
||||
items.push(`### ${section.title}`)
|
||||
items.push("")
|
||||
|
||||
for (const link of section.links) {
|
||||
addNavLink(items, link, baseUrl, 0, titleMap)
|
||||
}
|
||||
|
||||
items.push("")
|
||||
}
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== "GET") {
|
||||
return res.status(405).json({ error: "Method not allowed" })
|
||||
@@ -58,6 +105,38 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
"This file contains the complete documentation for Kilo Code, the leading open source agentic engineering platform.",
|
||||
)
|
||||
sections.push("")
|
||||
const protocol = req.headers["x-forwarded-proto"] || "https"
|
||||
const host = req.headers.host || "kilo.ai"
|
||||
const baseUrl = `${protocol}://${host}`
|
||||
const titleMap = buildTitleMap(markdownFiles, pagesDir)
|
||||
|
||||
sections.push("## Page Index")
|
||||
sections.push("")
|
||||
sections.push("Each page is available as raw markdown via the /api/raw-markdown endpoint.")
|
||||
sections.push("")
|
||||
|
||||
const navGroups = [
|
||||
{ title: "Getting Started", nav: Nav.GettingStartedNav },
|
||||
{ title: "Code with AI", nav: Nav.CodeWithAiNav },
|
||||
{ title: "Customize", nav: Nav.CustomizeNav },
|
||||
{ title: "Collaborate", nav: Nav.CollaborateNav },
|
||||
{ title: "Automate", nav: Nav.AutomateNav },
|
||||
{ title: "Deploy & Secure", nav: Nav.DeploySecureNav },
|
||||
{ title: "Contributing", nav: Nav.ContributingNav },
|
||||
{ title: "AI Providers", nav: Nav.AiProvidersNav },
|
||||
{ title: "Gateway", nav: Nav.GatewayNav },
|
||||
{ title: "Tools", nav: Nav.ToolsNav },
|
||||
]
|
||||
|
||||
for (const group of navGroups) {
|
||||
sections.push(`## ${group.title}`)
|
||||
sections.push("")
|
||||
|
||||
for (const section of group.nav) {
|
||||
addNavSection(sections, section, baseUrl, titleMap)
|
||||
}
|
||||
}
|
||||
|
||||
sections.push("---")
|
||||
sections.push("")
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ This page reflects the actual implementation in the extension.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Install/update the Kilo Code CLI (latest) — see [CLI setup](/docs/cli)
|
||||
- Install/update the Kilo Code CLI (latest) — see [CLI setup](/docs/code-with-ai/platforms/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))
|
||||
|
||||
@@ -102,7 +102,7 @@ The Agent Manager requires proper authentication for full functionality, includi
|
||||
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](/docs/cli) for details
|
||||
- See [CLI setup](/docs/code-with-ai/platforms/cli) for details
|
||||
|
||||
### BYOK Limitations
|
||||
|
||||
@@ -131,7 +131,7 @@ Message transcripts are fetched from a signed blob and exclude internal checkpoi
|
||||
## Troubleshooting
|
||||
|
||||
- CLI not found or outdated
|
||||
- Install/update the CLI: [CLI setup](/docs/cli)
|
||||
- Install/update the CLI: [CLI setup](/docs/code-with-ai/platforms/cli)
|
||||
- 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
|
||||
@@ -146,6 +146,6 @@ Message transcripts are fetched from a signed blob and exclude internal checkpoi
|
||||
|
||||
## Related features
|
||||
|
||||
- [Sessions](/docs/advanced-usage/sessions)
|
||||
- [Auto-approving Actions](/docs/features/auto-approving-actions)
|
||||
- [CLI](/docs/cli)
|
||||
- [Sessions](/docs/collaborate/sessions-sharing)
|
||||
- [Auto-approving Actions](/docs/getting-started/settings/auto-approving-actions)
|
||||
- [CLI](/docs/code-with-ai/platforms/cli)
|
||||
|
||||
@@ -30,8 +30,8 @@ Kilo Code currently supports two main local model providers:
|
||||
|
||||
For detailed setup instructions, see:
|
||||
|
||||
- [Setting up Ollama](/docs/providers/ollama)
|
||||
- [Setting up LM Studio](/docs/providers/lmstudio)
|
||||
- [Setting up Ollama](/docs/ai-providers/ollama)
|
||||
- [Setting up LM Studio](/docs/ai-providers/lmstudio)
|
||||
|
||||
Both providers offer similar capabilities but with different user interfaces and workflows. Ollama provides more control through its command-line interface, while LM Studio offers a more user-friendly graphical interface.
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ Terminal Shell Integration is a key feature that enables Kilo Code to execute co
|
||||
|
||||
Shell integration is automatically enabled in Kilo Code and connects directly to your terminal's command execution lifecycle without requiring any setup from you. This built-in feature allows Kilo Code to:
|
||||
|
||||
- Execute commands on your behalf through the [`execute_command`](/docs/features/tools/execute-command) tool
|
||||
- Execute commands on your behalf through the [`execute_command`](/docs/automate/tools/execute-command) tool
|
||||
- Read command output in real-time without manual copy-pasting
|
||||
- Automatically detect and fix errors in running applications
|
||||
- Observe command exit codes to determine success or failure
|
||||
|
||||
@@ -86,4 +86,4 @@ This safety mechanism ensures you maintain control over which files are modified
|
||||
|
||||
## Learn More About Tools
|
||||
|
||||
For more detailed information about each tool, including complete parameter references and advanced usage patterns, see the [Tool Use Overview](/docs/features/tools/tool-use-overview) documentation.
|
||||
For more detailed information about each tool, including complete parameter references and advanced usage patterns, see the [Tool Use Overview](/docs/automate/tools) documentation.
|
||||
|
||||
@@ -170,7 +170,7 @@ To set the maximum time to wait for a response after a tool call to the MCP serv
|
||||
|
||||
MCP tool auto-approval works on a per-tool basis and is disabled by default. To configure auto-approval:
|
||||
|
||||
1. First enable the global "Use MCP servers" auto-approval option in [auto-approving-actions](/docs/features/auto-approving-actions)
|
||||
1. First enable the global "Use MCP servers" auto-approval option in [auto-approving-actions](/docs/getting-started/settings/auto-approving-actions)
|
||||
2. Navigate to Settings > Agent Behaviour > MCP Servers, then locate the specific tool you want to auto-approve
|
||||
3. Check the `Always allow` checkbox next to the tool name
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# codebase_search
|
||||
|
||||
{% callout type="info" title="Setup Required" %}
|
||||
The `codebase_search` tool is part of the [Codebase Indexing](/docs/features/codebase-indexing) feature. It requires additional setup including an embedding provider and vector database.
|
||||
The `codebase_search` tool is part of the [Codebase Indexing](/docs/customize/context/codebase-indexing) feature. It requires additional setup including an embedding provider and vector database.
|
||||
{% /callout %}
|
||||
|
||||
The `codebase_search` tool performs semantic searches across your entire codebase using AI embeddings. Unlike traditional text-based search, it understands the meaning of your queries and finds relevant code even when exact keywords don't match.
|
||||
|
||||
@@ -15,22 +15,22 @@ Tools are organized into logical groups based on their functionality:
|
||||
|
||||
| Category | Purpose | Tools | Common Use |
|
||||
| ------------------ | --------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
||||
| **Read Group** | File system reading and searching | [read_file](/docs/features/tools/read-file), [search_files](/docs/features/tools/search-files), [list_files](/docs/features/tools/list-files), [list_code_definition_names](/docs/features/tools/list-code-definition-names) | Code exploration and analysis |
|
||||
| **Edit Group** | File system modifications | [apply_diff](/docs/features/tools/apply-diff), [delete_file](/docs/features/tools/delete-file), [write_to_file](/docs/features/tools/write-to-file) | Code changes and file manipulation |
|
||||
| **Browser Group** | Web automation | [browser_action](/docs/features/tools/browser-action) | Web testing and interaction |
|
||||
| **Command Group** | System command execution | [execute_command](/docs/features/tools/execute-command) | Running scripts, building projects |
|
||||
| **MCP Group** | External tool integration | [use_mcp_tool](/docs/features/tools/use-mcp-tool), [access_mcp_resource](/docs/features/tools/access-mcp-resource) | Specialized functionality through external servers |
|
||||
| **Workflow Group** | Mode and task management | [switch_mode](/docs/features/tools/switch-mode), [new_task](/docs/features/tools/new-task), [ask_followup_question](/docs/features/tools/ask-followup-question), [attempt_completion](/docs/features/tools/attempt-completion), [update_todo_list](/docs/features/tools/update-todo-list) | Context switching and task organization |
|
||||
| **Read Group** | File system reading and searching | [read_file](/docs/automate/tools/read-file), [search_files](/docs/automate/tools/search-files), [list_files](/docs/automate/tools/list-files), [list_code_definition_names](/docs/automate/tools/list-code-definition-names) | Code exploration and analysis |
|
||||
| **Edit Group** | File system modifications | [apply_diff](/docs/automate/tools/apply-diff), [delete_file](/docs/automate/tools/delete-file), [write_to_file](/docs/automate/tools/write-to-file) | Code changes and file manipulation |
|
||||
| **Browser Group** | Web automation | [browser_action](/docs/automate/tools/browser-action) | Web testing and interaction |
|
||||
| **Command Group** | System command execution | [execute_command](/docs/automate/tools/execute-command) | Running scripts, building projects |
|
||||
| **MCP Group** | External tool integration | [use_mcp_tool](/docs/automate/tools/use-mcp-tool), [access_mcp_resource](/docs/automate/tools/access-mcp-resource) | Specialized functionality through external servers |
|
||||
| **Workflow Group** | Mode and task management | [switch_mode](/docs/automate/tools/switch-mode), [new_task](/docs/automate/tools/new-task), [ask_followup_question](/docs/automate/tools/ask-followup-question), [attempt_completion](/docs/automate/tools/attempt-completion), [update_todo_list](/docs/automate/tools/update-todo-list) | Context switching and task organization |
|
||||
|
||||
### Always Available Tools
|
||||
|
||||
Certain tools are accessible regardless of the current mode:
|
||||
|
||||
- [ask_followup_question](/docs/features/tools/ask-followup-question): Gather additional information from users
|
||||
- [attempt_completion](/docs/features/tools/attempt-completion): Signal task completion
|
||||
- [switch_mode](/docs/features/tools/switch-mode): Change operational modes
|
||||
- [new_task](/docs/features/tools/new-task): Create subtasks
|
||||
- [update_todo_list](/docs/features/tools/update-todo-list): Manage step-by-step task tracking
|
||||
- [ask_followup_question](/docs/automate/tools/ask-followup-question): Gather additional information from users
|
||||
- [attempt_completion](/docs/automate/tools/attempt-completion): Signal task completion
|
||||
- [switch_mode](/docs/automate/tools/switch-mode): Change operational modes
|
||||
- [new_task](/docs/automate/tools/new-task): Create subtasks
|
||||
- [update_todo_list](/docs/automate/tools/update-todo-list): Manage step-by-step task tracking
|
||||
|
||||
## Available Tools
|
||||
|
||||
@@ -38,47 +38,47 @@ Certain tools are accessible regardless of the current mode:
|
||||
|
||||
These tools help Kilo Code understand your code and project:
|
||||
|
||||
- [read_file](/docs/features/tools/read-file) - Examines the contents of files
|
||||
- [search_files](/docs/features/tools/search-files) - Finds patterns across multiple files
|
||||
- [list_files](/docs/features/tools/list-files) - Maps your project's file structure
|
||||
- [list_code_definition_names](/docs/features/tools/list-code-definition-names) - Creates a structural map of your code
|
||||
- [read_file](/docs/automate/tools/read-file) - Examines the contents of files
|
||||
- [search_files](/docs/automate/tools/search-files) - Finds patterns across multiple files
|
||||
- [list_files](/docs/automate/tools/list-files) - Maps your project's file structure
|
||||
- [list_code_definition_names](/docs/automate/tools/list-code-definition-names) - Creates a structural map of your code
|
||||
|
||||
### Edit Tools
|
||||
|
||||
These tools help Kilo Code make changes to your code:
|
||||
|
||||
- [apply_diff](/docs/features/tools/apply-diff) - Makes precise, surgical changes to your code
|
||||
- [delete_file](/docs/features/tools/delete-file) - Removes files from your workspace
|
||||
- [write_to_file](/docs/features/tools/write-to-file) - Creates new files or completely rewrites existing ones
|
||||
- [apply_diff](/docs/automate/tools/apply-diff) - Makes precise, surgical changes to your code
|
||||
- [delete_file](/docs/automate/tools/delete-file) - Removes files from your workspace
|
||||
- [write_to_file](/docs/automate/tools/write-to-file) - Creates new files or completely rewrites existing ones
|
||||
|
||||
### Browser Tools
|
||||
|
||||
These tools help Kilo Code interact with web applications:
|
||||
|
||||
- [browser_action](/docs/features/tools/browser-action) - Automates browser interactions
|
||||
- [browser_action](/docs/automate/tools/browser-action) - Automates browser interactions
|
||||
|
||||
### Command Tools
|
||||
|
||||
These tools help Kilo Code execute commands:
|
||||
|
||||
- [execute_command](/docs/features/tools/execute-command) - Runs system commands and programs
|
||||
- [execute_command](/docs/automate/tools/execute-command) - Runs system commands and programs
|
||||
|
||||
### MCP Tools
|
||||
|
||||
These tools help Kilo Code connect with external services:
|
||||
|
||||
- [use_mcp_tool](/docs/features/tools/use-mcp-tool) - Uses specialized external tools
|
||||
- [access_mcp_resource](/docs/features/tools/access-mcp-resource) - Accesses external data sources
|
||||
- [use_mcp_tool](/docs/automate/tools/use-mcp-tool) - Uses specialized external tools
|
||||
- [access_mcp_resource](/docs/automate/tools/access-mcp-resource) - Accesses external data sources
|
||||
|
||||
### Workflow Tools
|
||||
|
||||
These tools help manage the conversation and task flow:
|
||||
|
||||
- [ask_followup_question](/docs/features/tools/ask-followup-question) - Gets additional information from you
|
||||
- [attempt_completion](/docs/features/tools/attempt-completion) - Presents final results
|
||||
- [switch_mode](/docs/features/tools/switch-mode) - Changes to a different mode for specialized tasks
|
||||
- [new_task](/docs/features/tools/new-task) - Creates a new subtask
|
||||
- [update_todo_list](/docs/features/tools/update-todo-list) - Tracks task progress with step-by-step checklists
|
||||
- [ask_followup_question](/docs/automate/tools/ask-followup-question) - Gets additional information from you
|
||||
- [attempt_completion](/docs/automate/tools/attempt-completion) - Presents final results
|
||||
- [switch_mode](/docs/automate/tools/switch-mode) - Changes to a different mode for specialized tasks
|
||||
- [new_task](/docs/automate/tools/new-task) - Creates a new subtask
|
||||
- [update_todo_list](/docs/automate/tools/update-todo-list) - Tracks task progress with step-by-step checklists
|
||||
|
||||
## Tool Calling Mechanism
|
||||
|
||||
@@ -211,24 +211,24 @@ Tools are made available based on the current mode:
|
||||
1. **Information Gathering**
|
||||
|
||||
```
|
||||
[ask_followup_question](/docs/features/tools/ask-followup-question) → [read_file](/docs/features/tools/read-file) → [search_files](/docs/features/tools/search-files)
|
||||
[ask_followup_question](/docs/automate/tools/ask-followup-question) → [read_file](/docs/automate/tools/read-file) → [search_files](/docs/automate/tools/search-files)
|
||||
```
|
||||
|
||||
2. **Code Modification**
|
||||
|
||||
```
|
||||
[read_file](/docs/features/tools/read-file) → [apply_diff](/docs/features/tools/apply-diff) → [attempt_completion](/docs/features/tools/attempt-completion)
|
||||
[read_file](/docs/automate/tools/read-file) → [apply_diff](/docs/automate/tools/apply-diff) → [attempt_completion](/docs/automate/tools/attempt-completion)
|
||||
```
|
||||
|
||||
3. **Task Management**
|
||||
|
||||
```
|
||||
[new_task](/docs/features/tools/new-task) → [switch_mode](/docs/features/tools/switch-mode) → [execute_command](/docs/features/tools/execute-command)
|
||||
[new_task](/docs/automate/tools/new-task) → [switch_mode](/docs/automate/tools/switch-mode) → [execute_command](/docs/automate/tools/execute-command)
|
||||
```
|
||||
|
||||
4. **Progress Tracking**
|
||||
```
|
||||
[update_todo_list](/docs/features/tools/update-todo-list) → [execute_command](/docs/features/tools/execute-command) → [update_todo_list](/docs/features/tools/update-todo-list)
|
||||
[update_todo_list](/docs/automate/tools/update-todo-list) → [execute_command](/docs/automate/tools/execute-command) → [update_todo_list](/docs/automate/tools/update-todo-list)
|
||||
```
|
||||
|
||||
## Error Handling and Recovery
|
||||
|
||||
@@ -10,7 +10,7 @@ description: "Learn how to use the Kilo Code chat interface effectively"
|
||||
{% /callout %}
|
||||
|
||||
{% callout type="note" title="Prefer quick completions?" %}
|
||||
If you're typing code in the editor and want AI to finish your line or block, check out [Autocomplete](/docs/basic-usage/autocomplete) instead. Chat is best for larger tasks, explanations, and multi-file changes.
|
||||
If you're typing code in the editor and want AI to finish your line or block, check out [Autocomplete](/docs/code-with-ai/features/autocomplete) instead. Chat is best for larger tasks, explanations, and multi-file changes.
|
||||
{% /callout %}
|
||||
|
||||
## Quick Setup
|
||||
@@ -41,7 +41,7 @@ Find the Kilo Code icon ({% kilo-code-icon /%}) in VS Code's Primary Side Bar. C
|
||||
{% callout type="info" title="Chat vs Autocomplete" %}
|
||||
**Use chat** when you need to describe what you want, ask questions, or make changes across multiple files.
|
||||
|
||||
**Use [autocomplete](/docs/basic-usage/autocomplete)** when you're already typing code and want the AI to finish your thought inline.
|
||||
**Use [autocomplete](/docs/code-with-ai/features/autocomplete)** when you're already typing code and want the AI to finish your thought inline.
|
||||
{% /callout %}
|
||||
|
||||
## The Chat Interface
|
||||
@@ -73,19 +73,19 @@ Find the Kilo Code icon ({% kilo-code-icon /%}) in VS Code's Primary Side Bar. C
|
||||
|
||||
## Common Mistakes to Avoid
|
||||
|
||||
| Instead of this... | Try this |
|
||||
| --------------------------------- | ------------------------------------------------------------------------- |
|
||||
| "Fix the code" | "Fix the bug in `calculateTotal` that returns incorrect results" |
|
||||
| Assuming Kilo knows context | Use `@` to reference specific files |
|
||||
| Multiple unrelated tasks | Submit one focused request at a time |
|
||||
| Technical jargon overload | Clear, straightforward language works best |
|
||||
| Using chat for tiny code changes. | Use [autocomplete](/docs/basic-usage/autocomplete) for inline completions |
|
||||
| Instead of this... | Try this |
|
||||
| --------------------------------- | ----------------------------------------------------------------------------------- |
|
||||
| "Fix the code" | "Fix the bug in `calculateTotal` that returns incorrect results" |
|
||||
| Assuming Kilo knows context | Use `@` to reference specific files |
|
||||
| Multiple unrelated tasks | Submit one focused request at a time |
|
||||
| Technical jargon overload | Clear, straightforward language works best |
|
||||
| Using chat for tiny code changes. | Use [autocomplete](/docs/code-with-ai/features/autocomplete) for inline completions |
|
||||
|
||||
**Why it matters:** Kilo Code works best when you communicate like you're talking to a smart teammate who needs clear direction.
|
||||
|
||||
## Suggested Responses
|
||||
|
||||
When Kilo Code needs more information to complete a task, it uses the [`ask_followup_question`](/docs/features/tools/ask-followup-question) tool. To make responding easier and faster, Kilo Code often provides suggested answers alongside the question.
|
||||
When Kilo Code needs more information to complete a task, it uses the [`ask_followup_question`](/docs/automate/tools/ask-followup-question) tool. To make responding easier and faster, Kilo Code often provides suggested answers alongside the question.
|
||||
|
||||
{% image src="/docs/img/suggested-responses/suggested-responses.png" alt="Example of Kilo Code asking a question with suggested response buttons below it" width="800" caption="Suggested responses appear as clickable buttons below questions" /%}
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ When you need more capability than free models provide, these options deliver ex
|
||||
**Strategic file mentions:**
|
||||
|
||||
- Only include files directly relevant to the task
|
||||
- Use [`@folder/`](/docs/basic-usage/context-mentions) for broad context, specific files for targeted work
|
||||
- Use [`@folder/`](/docs/code-with-ai/agents/context-mentions) for broad context, specific files for targeted work
|
||||
|
||||
### Model Switching Strategies
|
||||
|
||||
@@ -233,7 +233,7 @@ When you need more capability than free models provide, these options deliver ex
|
||||
|
||||
**Optimize conversation length:**
|
||||
|
||||
- Use [Checkpoints](/docs/features/checkpoints) to reset context
|
||||
- Use [Checkpoints](/docs/code-with-ai/features/checkpoints) to reset context
|
||||
- Start fresh conversations for unrelated tasks
|
||||
- Archive completed work
|
||||
|
||||
@@ -257,19 +257,19 @@ When you need more capability than free models provide, these options deliver ex
|
||||
|
||||
**Free tier foundation:**
|
||||
|
||||
- [OpenRouter](/docs/providers/openrouter) - Free models
|
||||
- [Groq](/docs/providers/groq) - Fast inference for supported models
|
||||
- [OpenRouter](/docs/ai-providers/openrouter) - Free models
|
||||
- [Groq](/docs/ai-providers/groq) - Fast inference for supported models
|
||||
- [Z.ai](https://z.ai/model-api) - Provides a free model GLM-4.5-Flash
|
||||
|
||||
**Budget tier options:**
|
||||
|
||||
- [DeepSeek](/docs/providers/deepseek) - Excellent value models
|
||||
- [Mistral](/docs/providers/mistral) - Specialized coding models
|
||||
- [DeepSeek](/docs/ai-providers/deepseek) - Excellent value models
|
||||
- [Mistral](/docs/ai-providers/mistral) - Specialized coding models
|
||||
|
||||
**Premium tier backup:**
|
||||
|
||||
- [Anthropic](/docs/providers/anthropic) - Claude for complex reasoning
|
||||
- [OpenAI](/docs/providers/openai) - GPT-4 for critical tasks
|
||||
- [Anthropic](/docs/ai-providers/anthropic) - Claude for complex reasoning
|
||||
- [OpenAI](/docs/ai-providers/openai) - GPT-4 for critical tasks
|
||||
|
||||
## Measuring Success
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ One thing that doesn't change: context window size matters for your workflow.
|
||||
- **Large codebases**: 256K+ tokens helps with cross-system understanding
|
||||
- **Massive systems**: 1M+ token models exist but effectiveness degrades at the extremes
|
||||
|
||||
Check [our provider docs](/docs/basic-usage/connecting-providers) for specific context limits on each model.
|
||||
Check [our provider docs](/docs/ai-providers) for specific context limits on each model.
|
||||
|
||||
{% callout type="tip" %}
|
||||
**Be thoughtful about Max Tokens settings for thinking models.** Every token you allocate to output 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.
|
||||
|
||||
@@ -25,7 +25,7 @@ Orchestrator Mode (formerly known as Boomerang Tasks) allows you to break down c
|
||||
|
||||
## Key Considerations
|
||||
|
||||
- **Approval Required:** By default, you must approve the creation and completion of each subtask. This can be automated via the [Auto-Approving Actions](/docs/features/auto-approving-actions#subtasks) settings if desired.
|
||||
- **Approval Required:** By default, you must approve the creation and completion of each subtask. This can be automated via the [Auto-Approving Actions](/docs/getting-started/settings/auto-approving-actions#subtasks) settings if desired.
|
||||
- **Context Isolation and Transfer:** Each subtask operates in complete isolation with its own conversation history. It does not automatically inherit the parent's context. Information must be explicitly passed:
|
||||
- **Down:** Via the initial instructions provided when the subtask is created.
|
||||
- **Up:** Via the final summary provided when the subtask finishes. Be mindful that only this summary returns to the parent.
|
||||
@@ -37,6 +37,6 @@ Orchestrator Mode provides a powerful way to manage complex development workflow
|
||||
Use subtasks to maintain clarity. If a request significantly shifts focus or requires a different expertise (mode), consider creating a subtask rather than overloading the current one.
|
||||
{% /callout %}
|
||||
|
||||
1. This context is passed via the `message` parameter of the [`new_task`](/docs/features/tools/new-task) tool.
|
||||
2. The mode for the subtask is specified via the `mode` parameter of the [`new_task`](/docs/features/tools/new-task) tool during initiation.
|
||||
3. This summary is passed via the `result` parameter of the [`attempt_completion`](/docs/features/tools/attempt-completion) tool when the subtask finishes.
|
||||
1. This context is passed via the `message` parameter of the [`new_task`](/docs/automate/tools/new-task) tool.
|
||||
2. The mode for the subtask is specified via the `mode` parameter of the [`new_task`](/docs/automate/tools/new-task) tool during initiation.
|
||||
3. This summary is passed via the `result` parameter of the [`attempt_completion`](/docs/automate/tools/attempt-completion) tool when the subtask finishes.
|
||||
|
||||
@@ -114,4 +114,4 @@ If using Cursor, go to **Settings** > **Cursor Settings** > **Tab**, and toggle
|
||||
|
||||
## Related Features
|
||||
|
||||
- [Code Actions](/docs/features/code-actions) - Context menu options for common coding tasks
|
||||
- [Code Actions](/docs/code-with-ai/features/code-actions) - Context menu options for common coding tasks
|
||||
|
||||
@@ -23,7 +23,7 @@ When **Enable editing through diffs** is checked:
|
||||
2. **Prevents Truncated Writes**: The system automatically detects and rejects attempts by the AI to write incomplete file content, which can happen with large files or complex instructions. This helps prevent corrupted files.
|
||||
|
||||
{% callout type="note" title="Disabling Fast Edits" %}
|
||||
If you uncheck **Enable editing through diffs**, Kilo will revert to writing the entire file content for every edit using the [`write_to_file`](/docs/features/tools/write-to-file) tool, instead of applying targeted changes with [`apply_diff`](/docs/features/tools/apply-diff). This full-write approach is generally slower for modifying existing files and leads to higher token usage.
|
||||
If you uncheck **Enable editing through diffs**, Kilo will revert to writing the entire file content for every edit using the [`write_to_file`](/docs/automate/tools/write-to-file) tool, instead of applying targeted changes with [`apply_diff`](/docs/automate/tools/apply-diff). This full-write approach is generally slower for modifying existing files and leads to higher token usage.
|
||||
{% /callout %}
|
||||
|
||||
## Match Precision
|
||||
|
||||
@@ -21,7 +21,7 @@ description: "Track and manage tasks with AI-generated todo lists"
|
||||
|
||||
**Manual triggers**:
|
||||
|
||||
- Ask Kilo to "use the [update_todo_list tool](/docs/features/tools/update-todo-list)"
|
||||
- Ask Kilo to "use the [update_todo_list tool](/docs/automate/tools/update-todo-list)"
|
||||
- Say "create a todo list"
|
||||
|
||||
**The bottom line**: Kilo decides what goes in the list, but you can provide feedback during approval dialogs.
|
||||
@@ -30,7 +30,7 @@ description: "Track and manage tasks with AI-generated todo lists"
|
||||
|
||||
## How todo lists are updated
|
||||
|
||||
Todo lists are managed with the [`update_todo_list` tool](/docs/features/tools/update-todo-list). Each time Kilo updates the list, it replaces the entire checklist with the latest view of the task.
|
||||
Todo lists are managed with the [`update_todo_list` tool](/docs/automate/tools/update-todo-list). Each time Kilo updates the list, it replaces the entire checklist with the latest view of the task.
|
||||
|
||||
Kilo updates the list when:
|
||||
|
||||
@@ -113,7 +113,7 @@ You can disable todo lists in Settings -> Advanced -> **Enable todo list tool**.
|
||||
|
||||
**When to use it**: Long workflows where constant interruptions slow you down.
|
||||
|
||||
**How to enable it**: Check the [Update Todo List auto-approval settings](/docs/features/auto-approving-actions#update-todo-list).
|
||||
**How to enable it**: Check the [Update Todo List auto-approval settings](/docs/getting-started/settings/auto-approving-actions#update-todo-list).
|
||||
|
||||
**The catch**: Less control, but faster execution.
|
||||
{% /callout %}
|
||||
|
||||
@@ -13,7 +13,7 @@ Orchestrate agents from your terminal. Plan, debug, and code fast with keyboard-
|
||||
|
||||
The Kilo Code CLI uses the same underlying technology that powers the IDE extensions, so you can expect the same workflow to handle agentic coding tasks from start to finish.
|
||||
|
||||
**Source code & issues (Kilo CLI 1.0):** [Kilo-Org/kilo](https://github.com/Kilo-Org/kilo) · [Report an issue](https://github.com/Kilo-Org/kilo/issues)
|
||||
**Source code & issues (Kilo CLI 1.0):** [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode) · [Report an issue](https://github.com/Kilo-Org/kilocode/issues)
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -167,7 +167,7 @@ Review your code locally before pushing — catch issues early without waiting f
|
||||
Configuration is managed through:
|
||||
|
||||
- `/connect` command for provider setup (interactive)
|
||||
- Config files in **`~/.config/kilo/`**: the CLI (Kilo CLI 1.0 from [Kilo-Org/kilo](https://github.com/Kilo-Org/kilo)) merges `config.json`, `opencode.json`, and `opencode.jsonc`. Use **`opencode.json`** (or `opencode.jsonc`) for provider, model, permission, and **MCP** settings. Restart the CLI after editing. See [Using MCP in the CLI](/automate/mcp/using-in-cli) for MCP config format.
|
||||
- Config files in **`~/.config/kilo/`**: the CLI (Kilo CLI 1.0 from [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode)) merges `config.json`, `opencode.json`, and `opencode.jsonc`. Use **`opencode.json`** (or `opencode.jsonc`) for provider, model, permission, and **MCP** settings. Restart the CLI after editing. See [Using MCP in the CLI](/docs/automate/mcp/using-in-cli) for MCP config format.
|
||||
- `kilo auth` for credential management
|
||||
|
||||
## Slash Commands
|
||||
@@ -290,7 +290,7 @@ Any directory allowed here inherits the same defaults as the current workspace.
|
||||
|
||||
## Configuration
|
||||
|
||||
The Kilo CLI is a fork of [OpenCode](https://opencode.ai) and supports the same configuration options. The CLI you install with `npm install -g @kilocode/cli` (Kilo CLI 1.0) is built from [Kilo-Org/kilo](https://github.com/Kilo-Org/kilo). For comprehensive configuration documentation, see the [OpenCode Config documentation](https://opencode.ai/docs/config).
|
||||
The Kilo CLI is a fork of [OpenCode](https://opencode.ai) and supports the same configuration options. The CLI you install with `npm install -g @kilocode/cli` (Kilo CLI 1.0) is built from [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode). For comprehensive configuration documentation, see the [OpenCode Config documentation](https://opencode.ai/docs/config).
|
||||
|
||||
### Config File Location (Kilo CLI 1.0)
|
||||
|
||||
@@ -345,20 +345,6 @@ Use `{env:VARIABLE_NAME}` syntax in config files to reference environment variab
|
||||
|
||||
For full details on all configuration options including compaction, file watchers, plugins, and experimental features, see the [OpenCode Config documentation](https://opencode.ai/docs/config).
|
||||
|
||||
## Config reference for providers
|
||||
|
||||
Kilo gives you the ability to bring your own keys for a number of model providers and AI gateways, like OpenRouter and Vercel AI Gateway. Each provider has unique configuration options and some let you set environment variables.
|
||||
|
||||
You can reference the [Provider Configuration Guide](https://github.com/Kilo-Org/kilocode/blob/main/cli/docs/PROVIDER_CONFIGURATION.md) for examples (same config format; for Kilo CLI 1.0 the file is `~/.config/kilo/opencode.json`). You can also run:
|
||||
|
||||
`kilo config`
|
||||
|
||||
to complete configuration with an interactive workflow on the command line.
|
||||
|
||||
{% callout type="tip" %}
|
||||
You can also use the `/config` slash command during an interactive session, which is equivalent to running `kilocode config`.
|
||||
{% /callout %}
|
||||
|
||||
## Interactive Mode
|
||||
|
||||
Interactive mode is the default mode when running Kilo Code without the `--auto` flag, designed to work interactively with a user through the console.
|
||||
|
||||
@@ -85,6 +85,15 @@ You can customize each Cloud Agent session by also defining env vars and startup
|
||||
- Bootstrapping tooling
|
||||
- Running setup scripts
|
||||
|
||||
### Setup Commands vs `.kilocode/setup-script`
|
||||
|
||||
- Cloud Agent executes **Setup Commands** configured in the Cloud UI/profile.
|
||||
- Cloud Agent does **not** automatically discover or run `.kilocode/setup-script`.
|
||||
- If you want to use `.kilocode/setup-script` in Cloud Agent, call it explicitly from Setup Commands, for example: `bash .kilocode/setup-script`.
|
||||
- If both are present, execution order is:
|
||||
1. Setup Commands (in the order you define them)
|
||||
2. Anything those commands invoke (such as `.kilocode/setup-script`)
|
||||
|
||||
## Skills
|
||||
|
||||
Cloud Agents support project-level [skills](/docs/code-with-ai/platforms/cli#skills) stored in your repository. When your repo is cloned, any skills in `.kilocode/skills/` are automatically available.
|
||||
|
||||
@@ -71,7 +71,7 @@ Low Depth indicates that developers may be trying AI but not trusting or shippin
|
||||
|
||||
**Actions:**
|
||||
|
||||
1. Enable [Managed Indexing](/docs/advanced-usage/managed-indexing) to improve context quality
|
||||
1. Enable [Managed Indexing](/docs/deploy-secure/managed-indexing) to improve context quality
|
||||
2. Review whether suggestions are relevant to your codebase
|
||||
3. Introduce chained workflows to increase multi-stage usage
|
||||
|
||||
@@ -235,6 +235,6 @@ Additional views for comparing multiple teams within an organization are planned
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Understand what each dimension measures](/docs/plans/adoption-dashboard/understanding-your-score)
|
||||
- [Learn strategies to improve your score](/docs/plans/adoption-dashboard/improving-your-score)
|
||||
- [Return to the dashboard overview](/docs/plans/adoption-dashboard/overview)
|
||||
- [Understand what each dimension measures](/docs/collaborate/adoption-dashboard/understanding-your-score)
|
||||
- [Learn strategies to improve your score](/docs/collaborate/adoption-dashboard/improving-your-score)
|
||||
- [Return to the dashboard overview](/docs/collaborate/adoption-dashboard/overview)
|
||||
|
||||
@@ -73,7 +73,7 @@ Linking coding → review → deploy actions significantly boosts your Depth sco
|
||||
|
||||
If acceptance rates are low, the issue is often context. The AI is making suggestions without understanding your codebase.
|
||||
|
||||
**Action:** Enable [Managed Indexing](/docs/advanced-usage/managed-indexing) to give the model vector-backed search across your repository.
|
||||
**Action:** Enable [Managed Indexing](/docs/deploy-secure/managed-indexing) to give the model vector-backed search across your repository.
|
||||
|
||||
Better context leads to:
|
||||
|
||||
@@ -86,7 +86,7 @@ Better context leads to:
|
||||
|
||||
Generated code that never runs is hard to trust. Teams that can verify AI output against live environments tend to retain more of that code long-term.
|
||||
|
||||
**Action:** Use [Kilo Deploy](/docs/advanced-usage/deploy) to spin up live URLs for branches, allowing your team to verify changes before merging.
|
||||
**Action:** Use [Kilo Deploy](/docs/deploy-secure/deploy) to spin up live URLs for branches, allowing your team to verify changes before merging.
|
||||
|
||||
---
|
||||
|
||||
@@ -190,5 +190,5 @@ Other ways to spread usage:
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Use the dashboard for team leadership](/docs/plans/adoption-dashboard/for-team-leads)
|
||||
- [Return to the dashboard overview](/docs/plans/adoption-dashboard/overview)
|
||||
- [Use the dashboard for team leadership](/docs/collaborate/adoption-dashboard/for-team-leads)
|
||||
- [Return to the dashboard overview](/docs/collaborate/adoption-dashboard/overview)
|
||||
|
||||
@@ -92,6 +92,6 @@ Click on any dimension card to view detailed analysis and improvement suggestion
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Understand what each dimension measures](/docs/plans/adoption-dashboard/understanding-your-score)
|
||||
- [Learn strategies to improve your score](/docs/plans/adoption-dashboard/improving-your-score)
|
||||
- [Use the dashboard for team leadership](/docs/plans/adoption-dashboard/for-team-leads)
|
||||
- [Understand what each dimension measures](/docs/collaborate/adoption-dashboard/understanding-your-score)
|
||||
- [Learn strategies to improve your score](/docs/collaborate/adoption-dashboard/improving-your-score)
|
||||
- [Use the dashboard for team leadership](/docs/collaborate/adoption-dashboard/for-team-leads)
|
||||
|
||||
@@ -147,5 +147,5 @@ Individual scores are most useful for personal development and self-assessment,
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Learn strategies to improve each dimension](/docs/plans/adoption-dashboard/improving-your-score)
|
||||
- [Use the dashboard for team leadership](/docs/plans/adoption-dashboard/for-team-leads)
|
||||
- [Learn strategies to improve each dimension](/docs/collaborate/adoption-dashboard/improving-your-score)
|
||||
- [Use the dashboard for team leadership](/docs/collaborate/adoption-dashboard/for-team-leads)
|
||||
|
||||
@@ -46,5 +46,5 @@ Here is the list of all events included in the Kilo Code audit logs:
|
||||
- Organization: Create, Settings Change, Purchase Credits
|
||||
- Organization Member: Remove, Change Role
|
||||
- User: Login, Logout, Accept Invite, Send Invite, Revoke Invite
|
||||
- [Custom Modes](/docs/plans/custom-modes): Create, Update, Delete
|
||||
- [SSO](/docs/plans/enterprise/SSO) (Enterprise Only): Auto Provision, Set Domain, Remove Domain
|
||||
- [Custom Modes](/docs/collaborate/teams/custom-modes-org): Create, Update, Delete
|
||||
- [SSO](/docs/collaborate/enterprise/sso) (Enterprise Only): Auto Provision, Set Domain, Remove Domain
|
||||
|
||||
@@ -57,7 +57,7 @@ Switch to **Kilo Teams** or **Kilo Enterprise** from other AI coding tools and e
|
||||
|
||||
**Step 2: Kilo Setup**
|
||||
|
||||
1. **Create organization** at [app.kilocode.com](https://app.kilocode.com)
|
||||
1. **Create organization** at [app.kilo.ai](https://app.kilo.ai)
|
||||
2. **Subscribe to Teams ($15/user/month)** or **Enterprise ([Contact Sales](https://kilo.ai/contact-sales))**
|
||||
3. **Configure team settings** and usage policies
|
||||
4. **Purchase initial AI credits** based on usage estimates
|
||||
@@ -355,7 +355,7 @@ Kilo Code also supports mode-specific rules (`.kilocode/rules-{mode}/`), which C
|
||||
- **Discord:** Join our migration support channel
|
||||
- **Consultation:** Schedule free migration planning call
|
||||
- **Documentation:**
|
||||
- [Business migration guide](/docs/plans/migration) (this page)
|
||||
- [Business migration guide](/docs/collaborate/enterprise/migration) (this page)
|
||||
- [Technical migration guide](/docs/getting-started/migrating) (rules and configurations)
|
||||
|
||||
## Success Stories
|
||||
@@ -383,9 +383,9 @@ Kilo Code also supports mode-specific rules (`.kilocode/rules-{mode}/`), which C
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Get started with your team](/docs/plans/getting-started)
|
||||
- [Explore team management features](/docs/plans/team-management)
|
||||
- [Understand billing and pricing](/docs/plans/billing)
|
||||
- [Get started with your team](/docs/collaborate/teams/getting-started)
|
||||
- [Explore team management features](/docs/collaborate/teams/team-management)
|
||||
- [Understand billing and pricing](/docs/collaborate/teams/billing)
|
||||
- [Migrate your rules and configurations](/docs/getting-started/migrating) (technical guide)
|
||||
|
||||
Ready to make the switch? Contact our migration team at migrations@kilo.ai to plan your transition to transparent AI coding.
|
||||
|
||||
@@ -41,5 +41,5 @@ Fill in your contact information and someone from our team will reach out soon t
|
||||
After enabling SSO:
|
||||
|
||||
- Invite new users with their company email domain.
|
||||
- Manage team access and roles from the **[Organization](/docs/plans/dashboard)** tab.
|
||||
- View user activity across the team in the **[Audit Logs](/docs/plans/enterprise/audit-logs)** tab
|
||||
- Manage team access and roles from the **[Organization](/docs/collaborate/adoption-dashboard/overview)** tab.
|
||||
- View user activity across the team in the **[Audit Logs](/docs/collaborate/enterprise/audit-logs)** tab
|
||||
|
||||
@@ -129,7 +129,7 @@ All costs are displayed in USD with detailed precision, helping you:
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Manage team billing settings](/docs/plans/billing)
|
||||
- [Configure team roles and permissions](/docs/plans/team-management)
|
||||
- [Manage team billing settings](/docs/collaborate/teams/billing)
|
||||
- [Configure team roles and permissions](/docs/collaborate/teams/team-management)
|
||||
|
||||
The usage analytics provide the insights needed to optimize your team's AI usage while maintaining visibility into costs and activity patterns.
|
||||
|
||||
@@ -21,7 +21,7 @@ Organization Owners can purchase Kilo credits on the [Organization dashboard](ht
|
||||
|
||||
Organization credits are purchased on behalf of all users in the organization. Every member of the organization can use the credits in the organization's balance with the Kilo Code model provider.
|
||||
|
||||
Using organization credits works exactly like spending [individual credits](/docs/basic-usage/adding-credits), except that the credits come from the organization's credit balance, rather than the individuals.
|
||||
Using organization credits works exactly like spending [individual credits](/docs/getting-started/adding-credits), except that the credits come from the organization's credit balance, rather than the individuals.
|
||||
|
||||
### Buying Organization Credits
|
||||
|
||||
@@ -47,7 +47,7 @@ You can remove empty seats at any time. Your next payment will reflect the small
|
||||
|
||||
Your next billing date will not change.
|
||||
|
||||
To fill empty seats or remove members ahead of seat deletion, see the [team management](/docs/plans/team-management) page.
|
||||
To fill empty seats or remove members ahead of seat deletion, see the [team management](/docs/collaborate/teams/team-management) page.
|
||||
|
||||
### Adding Seats
|
||||
|
||||
@@ -64,7 +64,7 @@ To fill empty seats or remove members ahead of seat deletion, see the [team mana
|
||||
3. **Select seats to remove** (must remove team members first)
|
||||
4. **Confirm reduction**
|
||||
|
||||
To fill empty seats or remove members ahead of seat deletion, see the [team management](/docs/plans/team-management) page.
|
||||
To fill empty seats or remove members ahead of seat deletion, see the [team management](/docs/collaborate/teams/team-management) page.
|
||||
|
||||
## Invoices
|
||||
|
||||
@@ -81,6 +81,6 @@ If payment fails repeatedly:
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Explore usage analytics](/docs/plans/analytics)
|
||||
- [Learn about team roles and permissions](/docs/plans/team-management)
|
||||
- [Learn about team management](/docs/plans/team-management)
|
||||
- [Explore usage analytics](/docs/collaborate/teams/analytics)
|
||||
- [Learn about team roles and permissions](/docs/collaborate/teams/team-management)
|
||||
- [Learn about team management](/docs/collaborate/teams/team-management)
|
||||
|
||||
@@ -162,6 +162,6 @@ Manage your Kilo Teams plan and seat allocation.
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Learn about team management](/docs/plans/team-management)
|
||||
- [Understand billing and credits](/docs/plans/billing)
|
||||
- [Explore usage analytics](/docs/plans/analytics)
|
||||
- [Learn about team management](/docs/collaborate/teams/team-management)
|
||||
- [Understand billing and credits](/docs/collaborate/teams/billing)
|
||||
- [Explore usage analytics](/docs/collaborate/teams/analytics)
|
||||
|
||||
@@ -76,6 +76,6 @@ You can find the dedicated Teams support methods directly on your Organization's
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Learn about team roles and permissions](/docs/plans/team-management)
|
||||
- [Explore the dashboard features](/docs/plans/dashboard)
|
||||
- [Set up team management policies](/docs/plans/team-management)
|
||||
- [Learn about team roles and permissions](/docs/collaborate/teams/team-management)
|
||||
- [Explore the dashboard features](/docs/collaborate/adoption-dashboard/overview)
|
||||
- [Set up team management policies](/docs/collaborate/teams/team-management)
|
||||
|
||||
@@ -11,7 +11,7 @@ Owners have full administrative oversight including billing, seat allocation, an
|
||||
|
||||
Only Owners can conduct team management activities.
|
||||
|
||||
Members can use the Kilo Code extension and see data on the team's usage in the [usage dashboard](/docs/plans/analytics).
|
||||
Members can use the Kilo Code extension and see data on the team's usage in the [usage dashboard](/docs/collaborate/teams/analytics).
|
||||
|
||||
## Adding Team Members
|
||||
|
||||
@@ -53,8 +53,8 @@ The Organization tab shows:
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Understand billing and credits](/docs/plans/billing)
|
||||
- [Explore usage analytics](/docs/plans/analytics)
|
||||
- [Learn about team roles and permissions](/docs/plans/team-management)
|
||||
- [Understand billing and credits](/docs/collaborate/teams/billing)
|
||||
- [Explore usage analytics](/docs/collaborate/teams/analytics)
|
||||
- [Learn about team roles and permissions](/docs/collaborate/teams/team-management)
|
||||
|
||||
Effective team management ensures your organization maximizes the benefits of AI-assisted development while maintaining cost control and security.
|
||||
|
||||
@@ -11,7 +11,6 @@ These pages document the architecture and design of current or planned features,
|
||||
| ---------------------------------------------------------------------------------------- | ------------------------------------------------ |
|
||||
| [Agent Observability](/docs/contributing/architecture/agent-observability) | Observability and monitoring for agentic systems |
|
||||
| [Benchmarking](/docs/contributing/architecture/benchmarking) | Benchmarking Kilo Code across models and agents |
|
||||
| [Annual Billing](/docs/contributing/architecture/annual-billing) | Annual subscription billing |
|
||||
| [Enterprise MCP Controls](/docs/contributing/architecture/enterprise-mcp-controls) | Admin controls for MCP server allowlists |
|
||||
| [MCP OAuth Authorization](/docs/contributing/architecture/mcp-oauth-authorization) | OAuth 2.1-based authorization for MCP servers |
|
||||
| [Onboarding Improvements](/docs/contributing/architecture/onboarding-improvements) | User onboarding and engagement features |
|
||||
|
||||
@@ -144,4 +144,4 @@ The project uses:
|
||||
## Further Reading
|
||||
|
||||
- [Development Environment](/docs/contributing/development-environment) - Setup guide
|
||||
- [Tools Reference](/docs/features/tools/tool-use-overview) - Available tools
|
||||
- [Tools Reference](/docs/automate/tools) - Available tools
|
||||
|
||||
@@ -6,11 +6,9 @@ description: "Set up your development environment for contributing"
|
||||
# Development Environment
|
||||
|
||||
{% callout type="info" %}
|
||||
**New versions of the VS Code extension and CLI are being developed in [Kilo-Org/Kilo](https://github.com/Kilo-Org/Kilo)** (extension at `packages/kilo-vscode`, CLI at `packages/opencode`). For extension and CLI development, please head over to that repository.
|
||||
**New versions of the VS Code extension and CLI are being developed in [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode)** (extension at `packages/kilo-vscode`, CLI at `packages/opencode`). For extension and CLI development, please head over to that repository.
|
||||
{% /callout %}
|
||||
|
||||
<!-- Please refer to the [DEVELOPMENT.md](https://github.com/Kilo-Org/kilocode/blob/main/DEVELOPMENT.md) guide in the main repository for detailed instructions on setting up the development environment. -->
|
||||
|
||||
This document will help you set up your development environment and understand how to work with the codebase. Whether you're fixing bugs, adding features, or just exploring the code, this guide will get you started.
|
||||
|
||||
## Prerequisites
|
||||
@@ -18,7 +16,7 @@ This document will help you set up your development environment and understand h
|
||||
Before you begin, make sure you have the following installed:
|
||||
|
||||
1. **Git** - For version control
|
||||
2. **Node.js** (version [v20.18.1](https://github.com/Kilo-Org/kilocode/blob/main/.nvmrc) or higher recommended) and npm
|
||||
2. **Node.js** (version v20.18.1 (See `.nvmrc` for latest) or higher recommended) and npm
|
||||
3. **Visual Studio Code** - Our recommended IDE for development
|
||||
|
||||
## Getting Started
|
||||
@@ -52,7 +50,7 @@ While not strictly necessary for running the extension, these extensions are rec
|
||||
- [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) - Integrates ESLint into VS Code.
|
||||
- [Prettier - Code formatter](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode) - Integrates Prettier into VS Code.
|
||||
|
||||
The full list of recommended extensions is [here](https://github.com/Kilo-Org/kilocode/blob/main/.vscode/extensions.json)
|
||||
The full list of recommended extensions is in `.vscode/extensions.json`
|
||||
|
||||
### Project Structure
|
||||
|
||||
@@ -151,7 +149,7 @@ E2E tests verify the extension works correctly within VSCode:
|
||||
npm run test:integration
|
||||
```
|
||||
|
||||
For more details on E2E tests, see [e2e/VSCODE_INTEGRATION_TESTS.md](https://github.com/Kilo-Org/kilocode/blob/main/e2e/VSCODE_INTEGRATION_TESTS.md).
|
||||
For more details on E2E tests, see e2e/VSCODE_INTEGRATION_TESTS
|
||||
|
||||
## Linting and Type Checking
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ If you need help with your contribution:
|
||||
|
||||
- Join our [Discord community](https://kilo.ai/discord) for real-time support
|
||||
- Ask questions on [GitHub Discussions](https://github.com/Kilo-Org/kilocode/discussions)
|
||||
- Visit our [Reddit community](https://www.reddit.com/r/KiloCode)
|
||||
- Visit our [Reddit community](https://www.reddit.com/r/kilocode)
|
||||
|
||||
## Recognition
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ You can configure context condensing thresholds and behavior on a per-profile ba
|
||||
### Maintaining Context Quality
|
||||
|
||||
- **Be specific in your initial task**: A clear task description helps create better summaries
|
||||
- **Use Memory Bank**: Combine with [Memory Bank](/docs/customize/context/memory-bank) for persistent project context that doesn't need to be condensed
|
||||
- **Use AGENTS.md**: Combine with [AGENTS.md](/docs/customize/agents-md) for persistent project context that doesn't need to be condensed
|
||||
- **Review the summary**: After condensing, the summary is visible in your chat history
|
||||
|
||||
## Troubleshooting
|
||||
@@ -97,6 +97,6 @@ If the condensed summary doesn't capture important details:
|
||||
|
||||
## Related Features
|
||||
|
||||
- [Memory Bank](/docs/customize/context/memory-bank) - Persistent context storage across sessions
|
||||
- [AGENTS.md](/docs/customize/agents-md) - Persistent context storage across sessions
|
||||
- [Large Projects](/docs/customize/context/large-projects) - Managing context for large codebases
|
||||
- [Codebase Indexing](/docs/customize/context/codebase-indexing) - Efficient code search and retrieval
|
||||
|
||||
@@ -21,7 +21,7 @@ Custom Instructions are IDE-wide and are applied across all workspaces and maint
|
||||
|
||||
{% image src="/docs/img/custom-instructions/custom-instructions.png" alt="Kilo Code Modes tab showing global custom instructions interface" width="600" caption="Kilo Code Modes tab showing global custom instructions interface" /%}
|
||||
|
||||
1. **Open Modes Tab:** Click the <Codicon name="organization" /> icon in the Kilo Code top menu bar
|
||||
1. **Open Modes Tab:** Click the <Codicon name="notebook" /> icon in the Kilo Code top menu bar
|
||||
2. **Find Section:** Find the "Custom Instructions for All Modes" section
|
||||
3. **Enter Instructions:** Enter your instructions in the text area
|
||||
4. **Save Changes:** Click "Done" to save your changes
|
||||
@@ -31,7 +31,7 @@ Custom Instructions are IDE-wide and are applied across all workspaces and maint
|
||||
Mode-specific instructions can be set using the Modes Tab
|
||||
|
||||
{% image src="/docs/img/custom-instructions/custom-instructions-3.png" alt="Kilo Code Modes tab showing mode-specific custom instructions interface" width="600" caption="Kilo Code Modes tab showing mode-specific custom instructions interface" /%}
|
||||
* **Open Tab:** Click the <Codicon name="organization" /> icon in the Kilo Code top menu bar
|
||||
* **Open Tab:** Click the <Codicon name="notebook" /> icon in the Kilo Code top menu bar
|
||||
* **Select Mode:** Under the Modes heading, click the button for the mode you want to customize
|
||||
* **Enter Instructions:** Enter your instructions in the text area under "Mode-specific Custom Instructions (optional)"
|
||||
* **Save Changes:** Click "Done" to save your changes
|
||||
@@ -40,9 +40,20 @@ Mode-specific instructions can be set using the Modes Tab
|
||||
If the mode itself is global (not workspace-specific), any custom instructions you set for it will also apply globally for that mode across all workspaces.
|
||||
{% /callout %}
|
||||
|
||||
## Mode-Specific Instructions from Files
|
||||
|
||||
For version-controlled mode instructions, use the mode rules file paths documented in [Custom Modes](/docs/customize/custom-modes#mode-specific-instructions-via-filesdirectories):
|
||||
|
||||
- Preferred: `.kilo/rules-{mode-slug}/` (directory)
|
||||
- Fallback: `.kilorules-{mode-slug}` (single file)
|
||||
|
||||
{% callout type="info" title="Legacy Naming Note" %}
|
||||
Older naming like `.clinerules-{mode-slug}` is not the recommended path for current Kilo mode-specific instructions.
|
||||
{% /callout %}
|
||||
|
||||
## Related Features
|
||||
|
||||
- [Custom Modes](/docs/customize/custom-modes)
|
||||
- [Custom Rules](/docs/customize/custom-rules)
|
||||
- [Settings Management](/docs/getting-started/settings)
|
||||
- [Auto-Approval Settings](/docs/features/auto-approving-actions)
|
||||
- [Auto-Approval Settings](/docs/getting-started/settings/auto-approving-actions)
|
||||
|
||||
@@ -74,7 +74,7 @@ Modes are managed from the Modes area in Kilo Code. Depending on your UI layout,
|
||||
|
||||
1. Open the Modes area from the mode selector in the chat panel (or via the <Codicon name="notebook" /> icon if shown)
|
||||
2. Click the Import Mode button (upload icon)
|
||||
3. Select the mode's YAML file
|
||||
3. Select the mode's YAML file (`.yaml`)
|
||||
4. Choose the import level:
|
||||
- **Project:** Available only in current workspace (saved to `.kilocodemodes` file)
|
||||
- **Global:** Available in all projects (saved to global settings)
|
||||
@@ -121,11 +121,16 @@ The interface provides fields for Name, Slug, Description, Save Location, Role D
|
||||
|
||||
You can directly edit the configuration files to create or modify custom modes. This method offers the most control over all properties. Kilo Code now supports both YAML (preferred) and JSON formats.
|
||||
|
||||
- **Global Modes:** Edit the `custom_modes.yaml` (preferred) or `custom_modes.json` file. Open the Modes area, click <Codicon name="gear" /> next to Global Modes, then choose "Edit Global Modes"
|
||||
- **Project Modes:** Edit the `.kilocodemodes` file (which can be YAML or JSON) in your project root. Open the Modes area, click <Codicon name="gear" /> next to Project Modes, then choose "Edit Project Modes"
|
||||
- **Global Modes:** Edit `custom_modes.yaml` (primary). `custom_modes.json` is a legacy fallback and may still exist in older setups.
|
||||
- **Project Modes:** Edit `.kilocodemodes` in your project root (YAML preferred; JSON still supported for compatibility).
|
||||
- **Open from UI:** Open the Modes area, click <Codicon name="gear" /> next to Global or Project Modes, then choose **Edit Global Modes** or **Edit Project Modes**.
|
||||
|
||||
These files define an array/list of custom modes.
|
||||
|
||||
{% callout type="info" title="Why JSON Files May Still Exist" %}
|
||||
If you see both YAML and JSON mode files, this is usually from legacy configuration. Kilo Code reads YAML first and does not keep both files synchronized line-by-line. In practice, edit YAML unless you have a specific reason to stay on JSON.
|
||||
{% /callout %}
|
||||
|
||||
## YAML Configuration Format (Preferred)
|
||||
|
||||
YAML is now the preferred format for defining custom modes due to better readability, comment support, and cleaner multi-line strings.
|
||||
|
||||
@@ -221,4 +221,4 @@ If your custom rules aren't being properly followed:
|
||||
- [Custom Modes](/docs/customize/custom-modes)
|
||||
- [Custom Instructions](/docs/customize/custom-instructions)
|
||||
- [Settings Management](/docs/getting-started/settings)
|
||||
- [Auto-Approval Settings](/docs/features/auto-approving-actions)
|
||||
- [Auto-Approval Settings](/docs/getting-started/settings/auto-approving-actions)
|
||||
|
||||
@@ -27,7 +27,7 @@ Help Kilo understand your codebase better:
|
||||
|
||||
- [**Codebase Indexing**](/docs/customize/context/codebase-indexing) - Build a semantic index of your code for better context awareness
|
||||
- [**Context Condensing**](/docs/customize/context/context-condensing) - Summarize older context to stay within limits
|
||||
- [**Memory Bank**](/docs/customize/context/memory-bank) - Store project context, decisions, and important information
|
||||
- [**AGENTS.md**](/docs/customize/agents-md) - Store project context, decisions, and important information
|
||||
- [**Large Projects**](/docs/customize/context/large-projects) - Best practices for working with monorepos and large codebases
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -13,7 +13,7 @@ Prompt engineering is the art of crafting effective instructions for AI models l
|
||||
- **Bad:** Fix the code.
|
||||
- **Good:** Fix the bug in the `calculateTotal` function that causes it to return incorrect results.
|
||||
|
||||
- **Provide Context:** Use [Context Mentions](/docs/basic-usage/context-mentions) to refer to specific files, folders, or problems.
|
||||
- **Provide Context:** Use [Context Mentions](/docs/code-with-ai/agents/context-mentions) to refer to specific files, folders, or problems.
|
||||
- **Good:** `@/src/utils.ts` Refactor the `calculateTotal` function to use async/await.
|
||||
|
||||
- **Break Down Tasks:** Divide complex tasks into smaller, well-defined steps.
|
||||
|
||||
@@ -26,10 +26,10 @@ Workflows are markdown files stored in `.kilocode/workflows/`:
|
||||
|
||||
Workflows can leverage:
|
||||
|
||||
- [Built-in tools](/docs/features/tools/tool-use-overview): [`read_file()`](/docs/features/tools/read-file), [`search_files()`](/docs/features/tools/search-files), [`execute_command()`](/docs/features/tools/execute-command)
|
||||
- [Built-in tools](/docs/automate/tools): [`read_file()`](/docs/automate/tools/read-file), [`search_files()`](/docs/automate/tools/search-files), [`execute_command()`](/docs/automate/tools/execute-command)
|
||||
- CLI tools: `gh`, `docker`, `npm`, custom scripts
|
||||
- [MCP integrations](/docs/automate/mcp/overview): Slack, databases, APIs
|
||||
- [Mode switching](/docs/code-with-ai/agents/using-modes): [`new_task()`](/docs/features/tools/new-task) for specialized contexts
|
||||
- [Mode switching](/docs/code-with-ai/agents/using-modes): [`new_task()`](/docs/automate/tools/new-task) for specialized contexts
|
||||
|
||||
## Common Workflow Patterns
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ Get started with Kilo Code by installing it on your preferred platform. Choose y
|
||||
## Pre-Release Extension
|
||||
|
||||
{% callout type="info" %}
|
||||
We're rebuilding Kilo Code from the ground up on the new [Kilo CLI](https://github.com/Kilo-Org/kilo). The pre-release extension is available for users who want to try the latest architecture and provide feedback, and don't mind some missing features and rough edges.
|
||||
We're rebuilding Kilo Code from the ground up on the new [Kilo CLI](https://github.com/Kilo-Org/kilocode). The pre-release extension is available for users who want to try the latest architecture and provide feedback, and don't mind some missing features and rough edges.
|
||||
{% /callout %}
|
||||
|
||||
The pre-release extension is a complete rebuild featuring:
|
||||
@@ -61,7 +61,7 @@ The pre-release extension is a complete rebuild featuring:
|
||||
|
||||
This is an early pre-release. Core features like chat, markdown rendering, authentication, and model/mode switching are working. Some features from the stable extension are still being implemented.
|
||||
|
||||
For the full feature status, see the [feature parity tracking document](https://github.com/Kilo-Org/kilo/blob/main/packages/kilo-vscode/docs/opencode-migration-plan.md).
|
||||
For the full feature status, see the [feature parity tracking document](https://github.com/Kilo-Org/kilocode/blob/main/packages/kilo-vscode/docs/opencode-migration-plan.md).
|
||||
|
||||
### Installing the Pre-Release
|
||||
|
||||
@@ -80,7 +80,7 @@ If you need to return to the stable version:
|
||||
|
||||
### Feedback and Issues
|
||||
|
||||
Report issues or provide feedback in the [Kilo-Org/kilo repository](https://github.com/Kilo-Org/kilo/issues).
|
||||
Report issues or provide feedback in the [Kilo-Org/kilocode repository](https://github.com/Kilo-Org/kilocode/issues).
|
||||
|
||||
## Manual Installations
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ description: "Get up and running with Kilo Code in minutes"
|
||||
|
||||
{% youtube url="https://www.youtube.com/watch?v=pO7zRLQS-p0" caption="This quick tour shows how Kilo Code handles a simple request from start to finish" /%}
|
||||
|
||||
After you [set up Kilo Code](/docs/getting-started/setting-up), follow these steps:
|
||||
After you [set up Kilo Code](/docs/getting-started/setup-authentication), follow these steps:
|
||||
|
||||
## Step by Step Guide
|
||||
|
||||
@@ -30,7 +30,7 @@ Type a clear, concise description of what you want Kilo Code to do in the chat b
|
||||
No special commands or syntax needed—just use plain English.
|
||||
|
||||
{% callout type="tip" title="Optional: Try Autocomplete" collapsed=true %}
|
||||
While chat is great for complex tasks, Kilo Code also offers **inline autocomplete** for quick code suggestions. Open any code file, start typing, and watch for ghost text suggestions. Press `Tab` to accept. [Learn more about Autocomplete →](/docs/basic-usage/autocomplete)
|
||||
While chat is great for complex tasks, Kilo Code also offers **inline autocomplete** for quick code suggestions. Open any code file, start typing, and watch for ghost text suggestions. Press `Tab` to accept. [Learn more about Autocomplete →](/docs/code-with-ai/features/autocomplete)
|
||||
{% /callout %}
|
||||
|
||||
{% image src="/docs/img/your-first-task/your-first-task-6.png" alt="Typing a task in the Kilo Code chat interface" width="500" caption="Enter your task in natural language - no special syntax required." /%}
|
||||
@@ -57,7 +57,7 @@ Kilo Code analyzes your request and proposes specific actions. These may include
|
||||
{% callout type="tip" %}
|
||||
The level of autonomy is configurable, allowing you to make the agent more or less autonomous.
|
||||
|
||||
You can learn more about [using modes](/docs/code-with-ai/agents/using-modes) and [auto-approving actions](/docs/features/auto-approving-actions).
|
||||
You can learn more about [using modes](/docs/code-with-ai/agents/using-modes) and [auto-approving actions](/docs/getting-started/settings/auto-approving-actions).
|
||||
{% /callout %}
|
||||
|
||||
### Step 5: Iterate
|
||||
|
||||
@@ -46,6 +46,6 @@ If you set the rate limit to 10 seconds, Kilo Code will wait at least 10 seconds
|
||||
- **Use Custom Instructions:** Provide custom instructions to guide Kilo Code's behavior and reduce the need for lengthy explanations in each prompt.
|
||||
- **Choose the Right Model:** Some models are more cost-effective than others. Consider using a smaller, faster model for tasks that don't require the full power of a larger model.
|
||||
- **Use Modes:** Different modes can access different tools, for example `Architect` can't modify code, which makes it a safe choice when analyzing a complex codebase, without worrying about accidentally allowing expensive operations.
|
||||
- **Disable MCP If Not Used:** If you're not using MCP (Model Context Protocol) features, consider [disabling it in Settings > Agent Behaviour > MCP Servers](/automate/mcp/overview) to significantly reduce the size of the system prompt and save tokens.
|
||||
- **Disable MCP If Not Used:** If you're not using MCP (Model Context Protocol) features, consider [disabling it in Settings > Agent Behaviour > MCP Servers](/docs/automate/mcp/overview) to significantly reduce the size of the system prompt and save tokens.
|
||||
|
||||
By understanding and managing your API usage, you can use Kilo Code effectively and efficiently.
|
||||
|
||||
@@ -41,7 +41,7 @@ Every task is automatically classified into one of these categories:
|
||||
|
||||
#### Understanding Task Completion
|
||||
|
||||
A task is considered "completed" when Kilo Code uses the [`attempt_completion`](/automate/tools/attempt-completion) tool to formally mark it as finished. Tasks without this completion marker are classified as incomplete, even if you consider them done. This distinction helps clean up abandoned or experimental tasks more aggressively.
|
||||
A task is considered "completed" when Kilo Code uses the [`attempt_completion`](/docs/automate/tools/attempt-completion) tool to formally mark it as finished. Tasks without this completion marker are classified as incomplete, even if you consider them done. This distinction helps clean up abandoned or experimental tasks more aggressively.
|
||||
|
||||
### Cleanup Process
|
||||
|
||||
@@ -102,7 +102,7 @@ Default: 30 days
|
||||
Minimum: 1 day
|
||||
```
|
||||
|
||||
Tasks successfully completed via the [`attempt_completion`](/automate/tools/attempt-completion) tool are retained for this period. These tasks typically represent finished work that may still be useful for reference.
|
||||
Tasks successfully completed via the [`attempt_completion`](/docs/automate/tools/attempt-completion) tool are retained for this period. These tasks typically represent finished work that may still be useful for reference.
|
||||
|
||||
#### Incomplete Tasks
|
||||
|
||||
@@ -240,9 +240,9 @@ Task data is stored in your VS Code global storage location:
|
||||
|
||||
## Related Features
|
||||
|
||||
- [**Checkpoints**](/code-with-ai/features/checkpoints): Version control for tasks that can be restored
|
||||
- [**Settings Management**](/getting-started/settings): Export/import settings including cleanup configuration
|
||||
- [**Task History**](/code-with-ai/agents/chat-interface): Managing and organizing your task history
|
||||
- [**Checkpoints**](/docs/code-with-ai/features/checkpoints): Version control for tasks that can be restored
|
||||
- [**Settings Management**](/docs/getting-started/settings): Export/import settings including cleanup configuration
|
||||
- [**Task History**](/docs/code-with-ai/agents/chat-interface): Managing and organizing your task history
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ These are just a few examples! Kilo Code supports many more providers including
|
||||
|
||||
### ChatGPT Plus/Pro Subscription
|
||||
|
||||
Already have a ChatGPT subscription? You can use it with Kilo Code through the [OpenAI ChatGPT provider](/docs/providers/openai-chatgpt-plus-pro)—no API key needed.
|
||||
Already have a ChatGPT subscription? You can use it with Kilo Code through the [OpenAI ChatGPT provider](/docs/ai-providers/openai-chatgpt-plus-pro)—no API key needed.
|
||||
|
||||
### OpenRouter
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@kilocode/kilo-gateway",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@kilocode/kilo-i18n",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "Kilo-specific i18n translations and overrides",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@kilocode/kilo-telemetry",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"description": "Telemetry for Kilo CLI - PostHog analytics integration",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@kilocode/kilo-ui",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"exports": {
|
||||
|
||||
@@ -5,4 +5,8 @@
|
||||
[data-slot="text-part-body"] {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
[data-slot="text-part-copy-wrapper"] {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "kilo-code",
|
||||
"displayName": "Kilo Code",
|
||||
"description": "Kilo Code AI Agent & Autocomplete",
|
||||
"version": "7.0.24",
|
||||
"displayName": "Kilo Code: AI Coding Agent, Copilot, and Autocomplete",
|
||||
"description": "Open Source AI coding agent that generates code from natural language, automates tasks, and runs terminal commands. Features inline autocomplete, browser automation, automated refactoring, and custom modes for planning, coding, and debugging. Supports 500+ AI models including Claude (Anthropic), Gemini, Grok, GPT, Codex and GLM.",
|
||||
"version": "7.0.25",
|
||||
"icon": "assets/icons/logo-outline-black.png",
|
||||
"publisher": "kilocode",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -22,7 +22,8 @@ const packagesDir = join(kiloVscodeDir, "..")
|
||||
const opencodeDir = join(packagesDir, "opencode")
|
||||
|
||||
const targetBinDir = join(kiloVscodeDir, "bin")
|
||||
const targetBinPath = join(targetBinDir, "kilo")
|
||||
const binName = process.platform === "win32" ? "kilo.exe" : "kilo"
|
||||
const targetBinPath = join(targetBinDir, binName)
|
||||
|
||||
function log(msg: string) {
|
||||
console.log(`[local-bin] ${msg}`)
|
||||
@@ -44,7 +45,7 @@ async function findKiloBinaryInOpencodeDist(): Promise<string | null> {
|
||||
|
||||
// Prefer the binary matching the current platform (e.g. cli-darwin-arm64)
|
||||
const tag = platformTag()
|
||||
const preferred = join(distDir, `@kilocode`, tag, "bin", "kilo")
|
||||
const preferred = join(distDir, `@kilocode`, tag, "bin", binName)
|
||||
try {
|
||||
statSync(preferred)
|
||||
return preferred
|
||||
@@ -52,7 +53,7 @@ async function findKiloBinaryInOpencodeDist(): Promise<string | null> {
|
||||
// fall through to generic search
|
||||
}
|
||||
|
||||
// Fallback: find any dist/**/bin/kilo
|
||||
// Fallback: find any dist/**/bin/kilo or kilo.exe
|
||||
const queue = [distDir]
|
||||
while (queue.length) {
|
||||
const dir = queue.pop()
|
||||
@@ -71,7 +72,7 @@ async function findKiloBinaryInOpencodeDist(): Promise<string | null> {
|
||||
queue.push(p)
|
||||
continue
|
||||
}
|
||||
if (e.isFile() && e.name === "kilo" && basename(dirname(p)) === "bin") {
|
||||
if (e.isFile() && (e.name === "kilo" || e.name === "kilo.exe") && basename(dirname(p)) === "bin") {
|
||||
return p
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,11 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
private trackedSessionIds: Set<string> = new Set()
|
||||
/** Per-session directory overrides (e.g., worktree paths registered by AgentManagerProvider). */
|
||||
private sessionDirectories = new Map<string, string>()
|
||||
/** Abort controller for the current loadMessages request; aborted when a new session is selected. */
|
||||
private loadMessagesAbort: AbortController | null = null
|
||||
private unsubscribeEvent: (() => void) | null = null
|
||||
private unsubscribeState: (() => void) | null = null
|
||||
private unsubscribeNotificationDismiss: (() => void) | null = null
|
||||
private webviewMessageDisposable: vscode.Disposable | null = null
|
||||
|
||||
/** Optional interceptor called before the standard message handler.
|
||||
@@ -283,6 +286,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
message.providerID,
|
||||
message.modelID,
|
||||
message.agent,
|
||||
message.variant,
|
||||
files,
|
||||
)
|
||||
break
|
||||
@@ -301,7 +305,9 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
this.trackedSessionIds.clear()
|
||||
break
|
||||
case "loadMessages":
|
||||
await this.handleLoadMessages(message.sessionID)
|
||||
// Don't await: allow parallel loads so rapid session switching
|
||||
// isn't blocked by slow responses for earlier sessions.
|
||||
void this.handleLoadMessages(message.sessionID)
|
||||
break
|
||||
case "syncSession":
|
||||
await this.handleSyncSession(message.sessionID)
|
||||
@@ -332,6 +338,11 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
vscode.env.openExternal(vscode.Uri.parse(message.url))
|
||||
}
|
||||
break
|
||||
case "openFile":
|
||||
if (message.filePath) {
|
||||
this.handleOpenFile(message.filePath, message.line, message.column)
|
||||
}
|
||||
break
|
||||
case "requestProviders":
|
||||
await this.fetchAndSendProviders()
|
||||
break
|
||||
@@ -430,6 +441,17 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
case "telemetry":
|
||||
TelemetryProxy.capture(message.event, message.properties)
|
||||
break
|
||||
case "persistVariant": {
|
||||
const stored = this.extensionContext?.globalState.get<Record<string, string>>("variantSelections") ?? {}
|
||||
stored[message.key] = message.value
|
||||
await this.extensionContext?.globalState.update("variantSelections", stored)
|
||||
break
|
||||
}
|
||||
case "requestVariants": {
|
||||
const variants = this.extensionContext?.globalState.get<Record<string, string>>("variantSelections") ?? {}
|
||||
this.postMessage({ type: "variantsLoaded", variants })
|
||||
break
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -444,6 +466,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
// Clean up any existing subscriptions (e.g., sidebar re-shown)
|
||||
this.unsubscribeEvent?.()
|
||||
this.unsubscribeState?.()
|
||||
this.unsubscribeNotificationDismiss?.()
|
||||
|
||||
try {
|
||||
const workspaceDir = this.getWorkspaceDirectory()
|
||||
@@ -491,6 +514,11 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
}
|
||||
})
|
||||
|
||||
// Subscribe to notification dismiss broadcast from other KiloProvider instances
|
||||
this.unsubscribeNotificationDismiss = this.connectionService.onNotificationDismissed(() => {
|
||||
this.fetchAndSendNotifications()
|
||||
})
|
||||
|
||||
// Get current state and push to webview
|
||||
const serverInfo = this.connectionService.getServerInfo()
|
||||
this.connectionState = this.connectionService.getConnectionState()
|
||||
@@ -575,25 +603,36 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
this.postMessage({
|
||||
type: "error",
|
||||
message: "Not connected to CLI backend",
|
||||
sessionID,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Abort any previous in-flight loadMessages request so the backend
|
||||
// isn't overwhelmed when the user switches sessions rapidly.
|
||||
this.loadMessagesAbort?.abort()
|
||||
const abort = new AbortController()
|
||||
this.loadMessagesAbort = abort
|
||||
|
||||
try {
|
||||
const workspaceDir = this.getWorkspaceDirectory(sessionID)
|
||||
const messagesData = await this.httpClient.getMessages(sessionID, workspaceDir)
|
||||
const messagesData = await this.httpClient.getMessages(sessionID, workspaceDir, abort.signal)
|
||||
|
||||
// If this request was aborted while awaiting, skip posting stale results
|
||||
if (abort.signal.aborted) return
|
||||
|
||||
// Update currentSession so fallback logic in handleSendMessage/handleAbort
|
||||
// references the correct session after switching to a historical session.
|
||||
// Non-blocking: don't let a failure here prevent messages from loading.
|
||||
// 404s are expected for cross-worktree sessions — use silent to suppress HTTP error logs.
|
||||
this.httpClient
|
||||
.getSession(sessionID, workspaceDir)
|
||||
.getSession(sessionID, workspaceDir, true)
|
||||
.then((session) => {
|
||||
if (!this.currentSession || this.currentSession.id === sessionID) {
|
||||
this.currentSession = session
|
||||
}
|
||||
})
|
||||
.catch((err) => console.error("[Kilo New] KiloProvider: Failed to fetch session for tracking:", err))
|
||||
.catch((err) => console.warn("[Kilo New] KiloProvider: getSession failed (non-critical):", err))
|
||||
|
||||
// Fetch current session status so the webview has the correct busy/idle
|
||||
// state after switching tabs (SSE events may have been missed).
|
||||
@@ -633,10 +672,13 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
messages,
|
||||
})
|
||||
} catch (error) {
|
||||
// Silently ignore aborted requests — the user switched to a different session
|
||||
if (abort.signal.aborted) return
|
||||
console.error("[Kilo New] KiloProvider: Failed to load messages:", error)
|
||||
this.postMessage({
|
||||
type: "error",
|
||||
message: error instanceof Error ? error.message : "Failed to load messages",
|
||||
sessionID,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -920,6 +962,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
await this.extensionContext.globalState.update("kilo.dismissedNotificationIds", [...existing, notificationId])
|
||||
}
|
||||
await this.fetchAndSendNotifications()
|
||||
this.connectionService.notifyNotificationDismissed(notificationId)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -979,6 +1022,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
providerID?: string,
|
||||
modelID?: string,
|
||||
agent?: string,
|
||||
variant?: string,
|
||||
files?: Array<{ mime: string; url: string }>,
|
||||
): Promise<void> {
|
||||
if (!this.httpClient) {
|
||||
@@ -1034,6 +1078,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
providerID,
|
||||
modelID,
|
||||
agent,
|
||||
variant,
|
||||
})
|
||||
} catch (error) {
|
||||
console.error("[Kilo New] KiloProvider: Failed to send message:", error)
|
||||
@@ -1265,6 +1310,28 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle openFile request from the webview — open a file in the VS Code editor.
|
||||
*/
|
||||
private handleOpenFile(filePath: string, line?: number, column?: number): void {
|
||||
const absolute = /^(?:\/|[a-zA-Z]:[\\/])/.test(filePath)
|
||||
const uri = absolute
|
||||
? vscode.Uri.file(filePath)
|
||||
: vscode.Uri.joinPath(vscode.Uri.file(this.getWorkspaceDirectory()), filePath)
|
||||
vscode.workspace.openTextDocument(uri).then(
|
||||
(doc) => {
|
||||
const options: vscode.TextDocumentShowOptions = { preview: true }
|
||||
if (line !== undefined && line > 0) {
|
||||
const col = column !== undefined && column > 0 ? column - 1 : 0
|
||||
const pos = new vscode.Position(line - 1, col)
|
||||
options.selection = new vscode.Range(pos, pos)
|
||||
}
|
||||
vscode.window.showTextDocument(doc, options)
|
||||
},
|
||||
(err) => console.error("[Kilo New] KiloProvider: Failed to open file:", uri.fsPath, err),
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle logout request from the webview.
|
||||
*/
|
||||
@@ -1473,6 +1540,7 @@ export class KiloProvider implements vscode.WebviewViewProvider, TelemetryProper
|
||||
dispose(): void {
|
||||
this.unsubscribeEvent?.()
|
||||
this.unsubscribeState?.()
|
||||
this.unsubscribeNotificationDismiss?.()
|
||||
this.webviewMessageDisposable?.dispose()
|
||||
this.trackedSessionIds.clear()
|
||||
this.sessionDirectories.clear()
|
||||
|
||||
@@ -94,7 +94,10 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
private async initializeState(): Promise<void> {
|
||||
const manager = this.getWorktreeManager()
|
||||
const state = this.getStateManager()
|
||||
if (!manager || !state) return
|
||||
if (!manager || !state) {
|
||||
this.pushEmptyState()
|
||||
return
|
||||
}
|
||||
|
||||
await state.load()
|
||||
|
||||
@@ -153,7 +156,17 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
}
|
||||
if (type === "agentManager.requestState") {
|
||||
void this.stateReady
|
||||
?.then(() => this.pushState())
|
||||
?.then(() => {
|
||||
this.pushState()
|
||||
// Refresh sessions after pushState so the webview's sessionsLoaded
|
||||
// handler is guaranteed to be registered (requestState fires from
|
||||
// onMount). Without this, the initial refreshSessions() in
|
||||
// initializeState() can race ahead of webview mount, causing
|
||||
// sessionsLoaded to never flip to true.
|
||||
if (this.state && this.state.getSessions().length > 0) {
|
||||
this.provider?.refreshSessions()
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
this.log("initializeState failed, pushing partial state:", err)
|
||||
this.pushState()
|
||||
@@ -228,11 +241,26 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
parentBranch: result.parentBranch,
|
||||
groupId,
|
||||
})
|
||||
|
||||
// Push state immediately so the sidebar shows the new worktree with a loading indicator
|
||||
this.pushState()
|
||||
this.postToWebview({
|
||||
type: "agentManager.worktreeSetup",
|
||||
status: "creating",
|
||||
message: "Setting up workspace...",
|
||||
branch: result.branch,
|
||||
worktreeId: worktree.id,
|
||||
})
|
||||
|
||||
return { worktree, result }
|
||||
}
|
||||
|
||||
/** Create a CLI session in a worktree directory. Returns null on failure. */
|
||||
private async createSessionInWorktree(worktreePath: string, branch: string): Promise<SessionInfo | null> {
|
||||
private async createSessionInWorktree(
|
||||
worktreePath: string,
|
||||
branch: string,
|
||||
worktreeId?: string,
|
||||
): Promise<SessionInfo | null> {
|
||||
let client: HttpClient
|
||||
try {
|
||||
client = this.connectionService.getHttpClient()
|
||||
@@ -241,6 +269,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
type: "agentManager.worktreeSetup",
|
||||
status: "error",
|
||||
message: "Not connected to CLI backend",
|
||||
worktreeId,
|
||||
})
|
||||
return null
|
||||
}
|
||||
@@ -250,6 +279,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
status: "starting",
|
||||
message: "Starting session...",
|
||||
branch,
|
||||
worktreeId,
|
||||
})
|
||||
|
||||
try {
|
||||
@@ -260,13 +290,14 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
type: "agentManager.worktreeSetup",
|
||||
status: "error",
|
||||
message: `Failed to create session: ${err}`,
|
||||
worktreeId,
|
||||
})
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/** Send worktreeSetup.ready + sessionMeta + pushState after worktree creation. */
|
||||
private notifyWorktreeReady(sessionId: string, result: CreateWorktreeResult): void {
|
||||
private notifyWorktreeReady(sessionId: string, result: CreateWorktreeResult, worktreeId?: string): void {
|
||||
this.pushState()
|
||||
this.postToWebview({
|
||||
type: "agentManager.worktreeSetup",
|
||||
@@ -274,6 +305,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
message: "Worktree ready",
|
||||
sessionId,
|
||||
branch: result.branch,
|
||||
worktreeId,
|
||||
})
|
||||
this.postToWebview({
|
||||
type: "agentManager.sessionMeta",
|
||||
@@ -295,21 +327,22 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
if (!created) return null
|
||||
|
||||
// Run setup script for new worktree (blocks until complete, shows in overlay)
|
||||
await this.runSetupScriptForWorktree(created.result.path, created.result.branch)
|
||||
await this.runSetupScriptForWorktree(created.result.path, created.result.branch, created.worktree.id)
|
||||
|
||||
const session = await this.createSessionInWorktree(created.result.path, created.result.branch)
|
||||
const session = await this.createSessionInWorktree(created.result.path, created.result.branch, created.worktree.id)
|
||||
if (!session) {
|
||||
const state = this.getStateManager()
|
||||
const manager = this.getWorktreeManager()
|
||||
state?.removeWorktree(created.worktree.id)
|
||||
await manager?.removeWorktree(created.result.path)
|
||||
this.pushState()
|
||||
return null
|
||||
}
|
||||
|
||||
const state = this.getStateManager()!
|
||||
state.addSession(session.id, created.worktree.id)
|
||||
this.registerWorktreeSession(session.id, created.result.path)
|
||||
this.notifyWorktreeReady(session.id, created.result)
|
||||
this.notifyWorktreeReady(session.id, created.result, created.worktree.id)
|
||||
this.log(`Created worktree ${created.worktree.id} with session ${session.id}`)
|
||||
return null
|
||||
}
|
||||
@@ -347,7 +380,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
if (!created) return null
|
||||
|
||||
// Run setup script for new worktree (blocks until complete, shows in overlay)
|
||||
await this.runSetupScriptForWorktree(created.result.path, created.result.branch)
|
||||
await this.runSetupScriptForWorktree(created.result.path, created.result.branch, created.worktree.id)
|
||||
|
||||
const state = this.getStateManager()!
|
||||
if (!state.getSession(sessionId)) {
|
||||
@@ -357,7 +390,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
}
|
||||
|
||||
this.registerWorktreeSession(sessionId, created.result.path)
|
||||
this.notifyWorktreeReady(sessionId, created.result)
|
||||
this.notifyWorktreeReady(sessionId, created.result, created.worktree.id)
|
||||
this.log(`Promoted session ${sessionId} to worktree ${created.worktree.id}`)
|
||||
return null
|
||||
}
|
||||
@@ -595,7 +628,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
}
|
||||
|
||||
/** Run the worktree setup script if configured. Blocks until complete. Shows progress in overlay. */
|
||||
private async runSetupScriptForWorktree(worktreePath: string, branch?: string): Promise<void> {
|
||||
private async runSetupScriptForWorktree(worktreePath: string, branch?: string, worktreeId?: string): Promise<void> {
|
||||
const root = this.getWorkspaceRoot()
|
||||
if (!root) return
|
||||
try {
|
||||
@@ -606,6 +639,7 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
status: "creating",
|
||||
message: "Running setup script...",
|
||||
branch,
|
||||
worktreeId,
|
||||
})
|
||||
const runner = new SetupScriptRunner(this.outputChannel, service)
|
||||
await runner.runIfConfigured({ worktreePath, repoPath: root })
|
||||
@@ -655,6 +689,17 @@ export class AgentManagerProvider implements vscode.Disposable {
|
||||
sessions: state.getSessions(),
|
||||
tabOrder: state.getTabOrder(),
|
||||
sessionsCollapsed: state.getSessionsCollapsed(),
|
||||
isGitRepo: true,
|
||||
})
|
||||
}
|
||||
|
||||
/** Push empty state when the workspace is not a git repo or has no workspace folder. */
|
||||
private pushEmptyState(): void {
|
||||
this.postToWebview({
|
||||
type: "agentManager.state",
|
||||
worktrees: [],
|
||||
sessions: [],
|
||||
isGitRepo: false,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ async function openKiloInNewTab(context: vscode.ExtensionContext, connectionServ
|
||||
dark: vscode.Uri.joinPath(context.extensionUri, "assets", "icons", "kilo-dark.svg"),
|
||||
}
|
||||
|
||||
const tabProvider = new KiloProvider(context.extensionUri, connectionService)
|
||||
const tabProvider = new KiloProvider(context.extensionUri, connectionService, context)
|
||||
tabProvider.resolveWebviewPanel(panel)
|
||||
|
||||
// Wait for the new panel to become active before locking the editor group.
|
||||
|
||||
@@ -9,6 +9,7 @@ export type ConnectionState = "connecting" | "connected" | "disconnected" | "err
|
||||
type SSEEventListener = (event: SSEEvent) => void
|
||||
type StateListener = (state: ConnectionState) => void
|
||||
type SSEEventFilter = (event: SSEEvent) => boolean
|
||||
type NotificationDismissListener = (notificationId: string) => void
|
||||
|
||||
/**
|
||||
* Shared connection service that owns the single ServerManager, HttpClient, and SSEClient.
|
||||
@@ -25,6 +26,7 @@ export class KiloConnectionService {
|
||||
|
||||
private readonly eventListeners: Set<SSEEventListener> = new Set()
|
||||
private readonly stateListeners: Set<StateListener> = new Set()
|
||||
private readonly notificationDismissListeners: Set<NotificationDismissListener> = new Set()
|
||||
|
||||
/**
|
||||
* Shared mapping used to resolve session scope for events that don't reliably include a sessionID.
|
||||
@@ -139,6 +141,25 @@ export class KiloConnectionService {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to notification dismiss events broadcast from any KiloProvider. Returns unsubscribe function.
|
||||
*/
|
||||
onNotificationDismissed(listener: NotificationDismissListener): () => void {
|
||||
this.notificationDismissListeners.add(listener)
|
||||
return () => {
|
||||
this.notificationDismissListeners.delete(listener)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a notification dismiss event to all subscribed KiloProvider instances.
|
||||
*/
|
||||
notifyNotificationDismissed(notificationId: string): void {
|
||||
for (const listener of this.notificationDismissListeners) {
|
||||
listener(notificationId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to connection state changes. Returns unsubscribe function.
|
||||
*/
|
||||
@@ -157,6 +178,7 @@ export class KiloConnectionService {
|
||||
this.serverManager.dispose()
|
||||
this.eventListeners.clear()
|
||||
this.stateListeners.clear()
|
||||
this.notificationDismissListeners.clear()
|
||||
this.messageSessionIdsByMessageId.clear()
|
||||
this.client = null
|
||||
this.sseClient = null
|
||||
|
||||
@@ -45,7 +45,7 @@ export class HttpClient {
|
||||
method: string,
|
||||
path: string,
|
||||
body?: unknown,
|
||||
options?: { directory?: string; allowEmpty?: boolean },
|
||||
options?: { directory?: string; allowEmpty?: boolean; silent?: boolean; signal?: AbortSignal },
|
||||
): Promise<T> {
|
||||
const url = `${this.baseUrl}${path}`
|
||||
|
||||
@@ -62,6 +62,7 @@ export class HttpClient {
|
||||
method,
|
||||
headers,
|
||||
body: body !== undefined ? JSON.stringify(body) : undefined,
|
||||
signal: options?.signal,
|
||||
})
|
||||
|
||||
// Read the raw response first so we can produce useful errors when JSON is empty/truncated.
|
||||
@@ -71,12 +72,14 @@ export class HttpClient {
|
||||
if (!response.ok) {
|
||||
const errorMessage = extractHttpErrorMessage(response.statusText, rawText)
|
||||
|
||||
console.error("[Kilo New] HTTP: ❌ Request failed", {
|
||||
method,
|
||||
path,
|
||||
status: response.status,
|
||||
errorMessage,
|
||||
})
|
||||
if (!options?.silent) {
|
||||
console.error("[Kilo New] HTTP: ❌ Request failed", {
|
||||
method,
|
||||
path,
|
||||
status: response.status,
|
||||
errorMessage,
|
||||
})
|
||||
}
|
||||
|
||||
throw new Error(`HTTP ${response.status}: ${errorMessage}`)
|
||||
}
|
||||
@@ -122,9 +125,10 @@ export class HttpClient {
|
||||
|
||||
/**
|
||||
* Get information about an existing session.
|
||||
* Set silent to suppress error logging (e.g. for expected 404s on cross-worktree sessions).
|
||||
*/
|
||||
async getSession(sessionId: string, directory: string): Promise<SessionInfo> {
|
||||
return this.request<SessionInfo>("GET", `/session/${sessionId}`, undefined, { directory })
|
||||
async getSession(sessionId: string, directory: string, silent?: boolean): Promise<SessionInfo> {
|
||||
return this.request<SessionInfo>("GET", `/session/${sessionId}`, undefined, { directory, silent })
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +214,7 @@ export class HttpClient {
|
||||
sessionId: string,
|
||||
parts: Array<{ type: "text"; text: string } | { type: "file"; mime: string; url: string }>,
|
||||
directory: string,
|
||||
options?: { providerID?: string; modelID?: string; agent?: string },
|
||||
options?: { providerID?: string; modelID?: string; agent?: string; variant?: string },
|
||||
): Promise<void> {
|
||||
const body: Record<string, unknown> = { parts }
|
||||
if (options?.providerID && options?.modelID) {
|
||||
@@ -220,6 +224,9 @@ export class HttpClient {
|
||||
if (options?.agent) {
|
||||
body.agent = options.agent
|
||||
}
|
||||
if (options?.variant) {
|
||||
body.variant = options.variant
|
||||
}
|
||||
|
||||
await this.request<void>("POST", `/session/${sessionId}/message`, body, { directory, allowEmpty: true })
|
||||
}
|
||||
@@ -227,12 +234,16 @@ export class HttpClient {
|
||||
/**
|
||||
* Get all messages for a session.
|
||||
*/
|
||||
async getMessages(sessionId: string, directory: string): Promise<Array<{ info: MessageInfo; parts: MessagePart[] }>> {
|
||||
async getMessages(
|
||||
sessionId: string,
|
||||
directory: string,
|
||||
signal?: AbortSignal,
|
||||
): Promise<Array<{ info: MessageInfo; parts: MessagePart[] }>> {
|
||||
return this.request<Array<{ info: MessageInfo; parts: MessagePart[] }>>(
|
||||
"GET",
|
||||
`/session/${sessionId}/message`,
|
||||
undefined,
|
||||
{ directory },
|
||||
{ directory, signal },
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -129,7 +129,8 @@ export class ServerManager {
|
||||
|
||||
private getCliPath(): string {
|
||||
// Always use the bundled binary from the extension directory
|
||||
const cliPath = path.join(this.context.extensionPath, "bin", "kilo")
|
||||
const binName = process.platform === "win32" ? "kilo.exe" : "kilo" // kilocode_change
|
||||
const cliPath = path.join(this.context.extensionPath, "bin", binName)
|
||||
console.log("[Kilo New] ServerManager: 📦 Using CLI path:", cliPath)
|
||||
return cliPath
|
||||
}
|
||||
|
||||
@@ -139,6 +139,8 @@ export interface ProviderModel {
|
||||
latest?: boolean
|
||||
// Actual shape returned by the server (Provider.Model)
|
||||
limit?: { context: number; input?: number; output: number }
|
||||
variants?: Record<string, Record<string, unknown>>
|
||||
capabilities?: { reasoning: boolean }
|
||||
}
|
||||
|
||||
// Provider definition
|
||||
|
||||
@@ -63,6 +63,13 @@ interface SetupState {
|
||||
message: string
|
||||
branch?: string
|
||||
error?: boolean
|
||||
worktreeId?: string
|
||||
}
|
||||
|
||||
interface WorktreeBusyState {
|
||||
reason: "setting-up" | "deleting"
|
||||
message?: string
|
||||
branch?: string
|
||||
}
|
||||
|
||||
/** Sidebar selection: LOCAL for workspace, worktree ID for a worktree, or null for an unassigned session. */
|
||||
@@ -232,10 +239,10 @@ const AgentManagerContent: Component = () => {
|
||||
const [managedSessions, setManagedSessions] = createSignal<ManagedSessionState[]>([])
|
||||
const [selection, setSelection] = createSignal<SidebarSelection>(LOCAL)
|
||||
const [repoBranch, setRepoBranch] = createSignal<string | undefined>()
|
||||
const [deletingWorktrees, setDeletingWorktrees] = createSignal<Set<string>>(new Set())
|
||||
const [loadingWorktrees, setLoadingWorktrees] = createSignal<Set<string>>(new Set())
|
||||
const [busyWorktrees, setBusyWorktrees] = createSignal<Map<string, WorktreeBusyState>>(new Map())
|
||||
const [worktreesLoaded, setWorktreesLoaded] = createSignal(false)
|
||||
const [sessionsLoaded, setSessionsLoaded] = createSignal(false)
|
||||
const [isGitRepo, setIsGitRepo] = createSignal(true)
|
||||
|
||||
const DEFAULT_SIDEBAR_WIDTH = 260
|
||||
const MIN_SIDEBAR_WIDTH = 200
|
||||
@@ -559,7 +566,14 @@ const AgentManagerContent: Component = () => {
|
||||
window.addEventListener("keydown", preventDefaults)
|
||||
|
||||
// When the panel regains focus (e.g. returning from terminal), focus the prompt
|
||||
const onWindowFocus = () => window.dispatchEvent(new Event("focusPrompt"))
|
||||
// and clear any stale body styles left by Kobalte modal overlays (dropdowns/dialogs
|
||||
// set pointer-events:none and overflow:hidden on body, but cleanup never runs if
|
||||
// focus leaves the webview before the overlay closes).
|
||||
const onWindowFocus = () => {
|
||||
document.body.style.pointerEvents = ""
|
||||
document.body.style.overflow = ""
|
||||
window.dispatchEvent(new Event("focusPrompt"))
|
||||
}
|
||||
window.addEventListener("focus", onWindowFocus)
|
||||
|
||||
// When a session is created while on local, replace the current pending tab with the real session.
|
||||
@@ -593,7 +607,15 @@ const AgentManagerContent: Component = () => {
|
||||
const ev = msg as AgentManagerWorktreeSetupMessage
|
||||
if (ev.status === "ready" || ev.status === "error") {
|
||||
const error = ev.status === "error"
|
||||
setSetup({ active: true, message: ev.message, branch: ev.branch, error })
|
||||
// Remove from busy map
|
||||
if (ev.worktreeId) {
|
||||
setBusyWorktrees((prev) => {
|
||||
const next = new Map(prev)
|
||||
next.delete(ev.worktreeId!)
|
||||
return next
|
||||
})
|
||||
}
|
||||
setSetup({ active: true, message: ev.message, branch: ev.branch, error, worktreeId: ev.worktreeId })
|
||||
globalThis.setTimeout(() => setSetup({ active: false, message: "" }), error ? 3000 : 500)
|
||||
if (!error && ev.sessionId) {
|
||||
session.selectSession(ev.sessionId)
|
||||
@@ -602,7 +624,15 @@ const AgentManagerContent: Component = () => {
|
||||
if (ms?.worktreeId) setSelection(ms.worktreeId)
|
||||
}
|
||||
} else {
|
||||
setSetup({ active: true, message: ev.message, branch: ev.branch })
|
||||
// Track this worktree as setting up and auto-select it in the sidebar
|
||||
if (ev.worktreeId) {
|
||||
setBusyWorktrees(
|
||||
(prev) =>
|
||||
new Map([...prev, [ev.worktreeId!, { reason: "setting-up", message: ev.message, branch: ev.branch }]]),
|
||||
)
|
||||
setSelection(ev.worktreeId)
|
||||
}
|
||||
setSetup({ active: true, message: ev.message, branch: ev.branch, worktreeId: ev.worktreeId })
|
||||
}
|
||||
}
|
||||
|
||||
@@ -620,6 +650,7 @@ const AgentManagerContent: Component = () => {
|
||||
const state = msg as AgentManagerStateMessage
|
||||
setWorktrees(state.worktrees)
|
||||
setManagedSessions(state.sessions)
|
||||
if (state.isGitRepo !== undefined) setIsGitRepo(state.isGitRepo)
|
||||
if (!worktreesLoaded()) setWorktreesLoaded(true)
|
||||
if (state.tabOrder) setWorktreeTabOrder(state.tabOrder)
|
||||
const current = session.currentSessionID()
|
||||
@@ -638,10 +669,10 @@ const AgentManagerContent: Component = () => {
|
||||
}
|
||||
// Recover sessions collapsed state from extension-persisted state
|
||||
if (state.sessionsCollapsed !== undefined) setSessionsCollapsed(state.sessionsCollapsed)
|
||||
// Clear deleting state for worktrees that have been removed
|
||||
// Clear busy state for worktrees that have been removed
|
||||
const ids = new Set(state.worktrees.map((wt) => wt.id))
|
||||
setDeletingWorktrees((prev) => {
|
||||
const next = new Set([...prev].filter((id) => ids.has(id)))
|
||||
setBusyWorktrees((prev) => {
|
||||
const next = new Map([...prev].filter(([id]) => ids.has(id)))
|
||||
return next.size === prev.size ? prev : next
|
||||
})
|
||||
}
|
||||
@@ -650,9 +681,9 @@ const AgentManagerContent: Component = () => {
|
||||
if ((msg as { type: string }).type === "agentManager.multiVersionProgress") {
|
||||
const ev = msg as unknown as AgentManagerMultiVersionProgressMessage
|
||||
if (ev.status === "done" && ev.groupId) {
|
||||
// Clear loading state for all worktrees in this group
|
||||
setLoadingWorktrees((prev) => {
|
||||
const next = new Set(prev)
|
||||
// Clear busy state for all worktrees in this group
|
||||
setBusyWorktrees((prev) => {
|
||||
const next = new Map(prev)
|
||||
for (const wt of worktrees()) {
|
||||
if (wt.groupId === ev.groupId) next.delete(wt.id)
|
||||
}
|
||||
@@ -669,7 +700,7 @@ const AgentManagerContent: Component = () => {
|
||||
const ms = managedSessions().find((s) => s.id === ev.sessionId)
|
||||
const wt = ms?.worktreeId ? worktrees().find((w) => w.id === ms.worktreeId) : undefined
|
||||
if (wt?.groupId) {
|
||||
setLoadingWorktrees((prev) => new Set([...prev, wt.id]))
|
||||
setBusyWorktrees((prev) => new Map([...prev, [wt.id, { reason: "setting-up" as const }]]))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -698,11 +729,11 @@ const AgentManagerContent: Component = () => {
|
||||
agent: ev.agent,
|
||||
files: ev.files,
|
||||
})
|
||||
// Clear loading state — use worktreeId from the message directly
|
||||
// Clear busy state — use worktreeId from the message directly
|
||||
// to avoid race condition where managedSessions() hasn't updated yet
|
||||
if (ev.worktreeId) {
|
||||
setLoadingWorktrees((prev) => {
|
||||
const next = new Set(prev)
|
||||
setBusyWorktrees((prev) => {
|
||||
const next = new Map(prev)
|
||||
next.delete(ev.worktreeId)
|
||||
return next
|
||||
})
|
||||
@@ -780,7 +811,7 @@ const AgentManagerContent: Component = () => {
|
||||
const wt = worktrees().find((w) => w.id === worktreeId)
|
||||
if (!wt) return
|
||||
const doDelete = () => {
|
||||
setDeletingWorktrees((prev) => new Set([...prev, wt.id]))
|
||||
setBusyWorktrees((prev) => new Map([...prev, [wt.id, { reason: "deleting" as const }]]))
|
||||
vscode.postMessage({ type: "agentManager.deleteWorktree", worktreeId: wt.id })
|
||||
if (selection() === wt.id) {
|
||||
const next = nextSelectionAfterDelete(
|
||||
@@ -1004,54 +1035,56 @@ const AgentManagerContent: Component = () => {
|
||||
<div class={`am-section ${sessionsCollapsed() ? "am-section-grow" : ""}`}>
|
||||
<div class="am-section-header">
|
||||
<span class="am-section-label">WORKTREES</span>
|
||||
<div class="am-section-actions">
|
||||
<DropdownMenu>
|
||||
<DropdownMenu.Trigger
|
||||
as={IconButton}
|
||||
icon="settings-gear"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="Worktree settings"
|
||||
/>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content>
|
||||
<DropdownMenu.Item onSelect={handleShowKeyboardShortcuts}>
|
||||
<DropdownMenu.ItemLabel>Keyboard Shortcuts</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item onSelect={handleConfigureSetupScript}>
|
||||
<DropdownMenu.ItemLabel>Worktree Setup Script</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu>
|
||||
<div class="am-split-button">
|
||||
<IconButton
|
||||
icon="plus"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="New Worktree"
|
||||
onClick={handleCreateWorktree}
|
||||
/>
|
||||
<DropdownMenu gutter={4} placement="bottom-end">
|
||||
<DropdownMenu.Trigger class="am-split-arrow" aria-label="Advanced worktree options">
|
||||
<Icon name="chevron-down" size="small" />
|
||||
</DropdownMenu.Trigger>
|
||||
<Show when={isGitRepo()}>
|
||||
<div class="am-section-actions">
|
||||
<DropdownMenu>
|
||||
<DropdownMenu.Trigger
|
||||
as={IconButton}
|
||||
icon="settings-gear"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="Worktree settings"
|
||||
/>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content class="am-split-menu">
|
||||
<DropdownMenu.Item onSelect={handleCreateWorktree}>
|
||||
<DropdownMenu.ItemLabel>New Worktree</DropdownMenu.ItemLabel>
|
||||
<DropdownMenu.Content>
|
||||
<DropdownMenu.Item onSelect={handleShowKeyboardShortcuts}>
|
||||
<DropdownMenu.ItemLabel>Keyboard Shortcuts</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item onSelect={showAdvancedWorktreeDialog}>
|
||||
<Icon name="layers" size="small" />
|
||||
<DropdownMenu.ItemLabel>New with Versions...</DropdownMenu.ItemLabel>
|
||||
<DropdownMenu.Item onSelect={handleConfigureSetupScript}>
|
||||
<DropdownMenu.ItemLabel>Worktree Setup Script</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu>
|
||||
<div class="am-split-button">
|
||||
<IconButton
|
||||
icon="plus"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="New Worktree"
|
||||
onClick={handleCreateWorktree}
|
||||
/>
|
||||
<DropdownMenu gutter={4} placement="bottom-end">
|
||||
<DropdownMenu.Trigger class="am-split-arrow" aria-label="Advanced worktree options">
|
||||
<Icon name="chevron-down" size="small" />
|
||||
</DropdownMenu.Trigger>
|
||||
<DropdownMenu.Portal>
|
||||
<DropdownMenu.Content class="am-split-menu">
|
||||
<DropdownMenu.Item onSelect={handleCreateWorktree}>
|
||||
<DropdownMenu.ItemLabel>New Worktree</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
<DropdownMenu.Separator />
|
||||
<DropdownMenu.Item onSelect={showAdvancedWorktreeDialog}>
|
||||
<Icon name="layers" size="small" />
|
||||
<DropdownMenu.ItemLabel>New with Versions...</DropdownMenu.ItemLabel>
|
||||
</DropdownMenu.Item>
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu.Portal>
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
<div class="am-worktree-list">
|
||||
<Show
|
||||
@@ -1065,118 +1098,131 @@ const AgentManagerContent: Component = () => {
|
||||
</div>
|
||||
}
|
||||
>
|
||||
{(() => {
|
||||
const [hoveredWt, setHoveredWt] = createSignal<string | null>(null)
|
||||
const [overClose, setOverClose] = createSignal(false)
|
||||
return (
|
||||
<For each={sortedWorktrees()}>
|
||||
{(wt, idx) => {
|
||||
const grouped = () => isGrouped(wt)
|
||||
const start = () => isGroupStart(wt, idx())
|
||||
const end = () => isGroupEnd(wt, idx())
|
||||
const busy = () => deletingWorktrees().has(wt.id) || loadingWorktrees().has(wt.id)
|
||||
const groupSize = () => {
|
||||
if (!wt.groupId) return 0
|
||||
return sortedWorktrees().filter((w) => w.groupId === wt.groupId).length
|
||||
}
|
||||
const sessions = createMemo(() => managedSessions().filter((ms) => ms.worktreeId === wt.id))
|
||||
const navHint = () => {
|
||||
const flat = [
|
||||
LOCAL as string,
|
||||
...sortedWorktrees().map((w) => w.id),
|
||||
...unassignedSessions().map((s) => s.id),
|
||||
]
|
||||
const active = selection() ?? session.currentSessionID() ?? ""
|
||||
return adjacentHint(wt.id, active, flat, kb().previousSession ?? "", kb().nextSession ?? "")
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Show when={start()}>
|
||||
<div class="am-wt-group-header">
|
||||
<Icon name="layers" size="small" />
|
||||
<span class="am-wt-group-label">{groupSize()} versions</span>
|
||||
</div>
|
||||
</Show>
|
||||
<HoverCard
|
||||
openDelay={100}
|
||||
closeDelay={100}
|
||||
placement="right-start"
|
||||
gutter={8}
|
||||
open={hoveredWt() === wt.id && !overClose()}
|
||||
onOpenChange={(open) => setHoveredWt(open ? wt.id : null)}
|
||||
trigger={
|
||||
<div
|
||||
class="am-worktree-item"
|
||||
classList={{
|
||||
"am-worktree-item-active": selection() === wt.id,
|
||||
"am-wt-grouped": grouped(),
|
||||
"am-wt-group-end": end(),
|
||||
}}
|
||||
data-sidebar-id={wt.id}
|
||||
onClick={() => selectWorktree(wt.id)}
|
||||
>
|
||||
<Icon name="branch" size="small" />
|
||||
<span class="am-worktree-branch">{worktreeLabel(wt)}</span>
|
||||
<Show when={!busy()} fallback={<Spinner class="am-worktree-spinner" />}>
|
||||
<div
|
||||
class="am-worktree-close"
|
||||
onMouseEnter={() => setOverClose(true)}
|
||||
onMouseLeave={() => setOverClose(false)}
|
||||
<Show when={!isGitRepo()}>
|
||||
<div class="am-not-git-notice">
|
||||
<Icon name="info" size="small" />
|
||||
<span>Not a git repository</span>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={isGitRepo()}>
|
||||
{(() => {
|
||||
const [hoveredWt, setHoveredWt] = createSignal<string | null>(null)
|
||||
const [overClose, setOverClose] = createSignal(false)
|
||||
return (
|
||||
<For each={sortedWorktrees()}>
|
||||
{(wt, idx) => {
|
||||
const grouped = () => isGrouped(wt)
|
||||
const start = () => isGroupStart(wt, idx())
|
||||
const end = () => isGroupEnd(wt, idx())
|
||||
const busy = () => busyWorktrees().has(wt.id)
|
||||
const groupSize = () => {
|
||||
if (!wt.groupId) return 0
|
||||
return sortedWorktrees().filter((w) => w.groupId === wt.groupId).length
|
||||
}
|
||||
const sessions = createMemo(() => managedSessions().filter((ms) => ms.worktreeId === wt.id))
|
||||
const navHint = () => {
|
||||
const flat = [
|
||||
LOCAL as string,
|
||||
...sortedWorktrees().map((w) => w.id),
|
||||
...unassignedSessions().map((s) => s.id),
|
||||
]
|
||||
const active = selection() ?? session.currentSessionID() ?? ""
|
||||
return adjacentHint(wt.id, active, flat, kb().previousSession ?? "", kb().nextSession ?? "")
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<Show when={start()}>
|
||||
<div class="am-wt-group-header">
|
||||
<Icon name="layers" size="small" />
|
||||
<span class="am-wt-group-label">{groupSize()} versions</span>
|
||||
</div>
|
||||
</Show>
|
||||
<HoverCard
|
||||
openDelay={100}
|
||||
closeDelay={100}
|
||||
placement="right-start"
|
||||
gutter={8}
|
||||
open={hoveredWt() === wt.id && !overClose()}
|
||||
onOpenChange={(open) => setHoveredWt(open ? wt.id : null)}
|
||||
trigger={
|
||||
<div
|
||||
class="am-worktree-item"
|
||||
classList={{
|
||||
"am-worktree-item-active": selection() === wt.id,
|
||||
"am-wt-grouped": grouped(),
|
||||
"am-wt-group-end": end(),
|
||||
}}
|
||||
data-sidebar-id={wt.id}
|
||||
onClick={() => selectWorktree(wt.id)}
|
||||
>
|
||||
<Show
|
||||
when={!busyWorktrees().has(wt.id)}
|
||||
fallback={<Spinner class="am-worktree-spinner" />}
|
||||
>
|
||||
<TooltipKeybind
|
||||
title="Delete worktree"
|
||||
keybind={kb().closeWorktree ?? ""}
|
||||
placement="top"
|
||||
<Icon name="branch" size="small" />
|
||||
</Show>
|
||||
<span class="am-worktree-branch">{worktreeLabel(wt)}</span>
|
||||
<Show when={!busyWorktrees().has(wt.id)}>
|
||||
<div
|
||||
class="am-worktree-close"
|
||||
onMouseEnter={() => setOverClose(true)}
|
||||
onMouseLeave={() => setOverClose(false)}
|
||||
>
|
||||
<IconButton
|
||||
icon="close-small"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="Delete worktree"
|
||||
onClick={(e: MouseEvent) => handleDeleteWorktree(wt.id, e)}
|
||||
/>
|
||||
</TooltipKeybind>
|
||||
<TooltipKeybind
|
||||
title="Delete worktree"
|
||||
keybind={kb().closeWorktree ?? ""}
|
||||
placement="top"
|
||||
>
|
||||
<IconButton
|
||||
icon="close-small"
|
||||
size="small"
|
||||
variant="ghost"
|
||||
label="Delete worktree"
|
||||
onClick={(e: MouseEvent) => handleDeleteWorktree(wt.id, e)}
|
||||
/>
|
||||
</TooltipKeybind>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div class="am-hover-card">
|
||||
<div class="am-hover-card-header">
|
||||
<div>
|
||||
<div class="am-hover-card-label">BRANCH</div>
|
||||
<div class="am-hover-card-branch">{wt.branch}</div>
|
||||
<div class="am-hover-card-meta">{formatRelativeDate(wt.createdAt)}</div>
|
||||
</div>
|
||||
<Show when={navHint()}>
|
||||
<span class="am-hover-card-keybind">{navHint()}</span>
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={wt.parentBranch}>
|
||||
<div class="am-hover-card-divider" />
|
||||
<div class="am-hover-card-row">
|
||||
<span class="am-hover-card-row-label">Base</span>
|
||||
<span class="am-hover-card-row-value">{wt.parentBranch}</span>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<div class="am-hover-card">
|
||||
<div class="am-hover-card-header">
|
||||
<div>
|
||||
<div class="am-hover-card-label">BRANCH</div>
|
||||
<div class="am-hover-card-branch">{wt.branch}</div>
|
||||
<div class="am-hover-card-meta">{formatRelativeDate(wt.createdAt)}</div>
|
||||
</div>
|
||||
<Show when={navHint()}>
|
||||
<span class="am-hover-card-keybind">{navHint()}</span>
|
||||
</Show>
|
||||
</div>
|
||||
<Show when={wt.parentBranch}>
|
||||
<div class="am-hover-card-divider" />
|
||||
<div class="am-hover-card-row">
|
||||
<span class="am-hover-card-row-label">Base</span>
|
||||
<span class="am-hover-card-row-value">{wt.parentBranch}</span>
|
||||
<span class="am-hover-card-row-label">Sessions</span>
|
||||
<span class="am-hover-card-row-value">{sessions().length}</span>
|
||||
</div>
|
||||
</Show>
|
||||
<div class="am-hover-card-divider" />
|
||||
<div class="am-hover-card-row">
|
||||
<span class="am-hover-card-row-label">Sessions</span>
|
||||
<span class="am-hover-card-row-value">{sessions().length}</span>
|
||||
</div>
|
||||
</div>
|
||||
</HoverCard>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
)
|
||||
})()}
|
||||
<Show when={worktrees().length === 0}>
|
||||
<button class="am-worktree-create" onClick={handleCreateWorktree}>
|
||||
<Icon name="plus" size="small" />
|
||||
<span>New Worktree</span>
|
||||
</button>
|
||||
</HoverCard>
|
||||
</>
|
||||
)
|
||||
}}
|
||||
</For>
|
||||
)
|
||||
})()}
|
||||
<Show when={worktrees().length === 0}>
|
||||
<button class="am-worktree-create" onClick={handleCreateWorktree}>
|
||||
<Icon name="plus" size="small" />
|
||||
<span>New Worktree</span>
|
||||
</button>
|
||||
</Show>
|
||||
</Show>
|
||||
</Show>
|
||||
</div>
|
||||
@@ -1360,23 +1406,48 @@ const AgentManagerContent: Component = () => {
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<Show when={setup().active}>
|
||||
<div class="am-setup-overlay">
|
||||
<div class="am-setup-card">
|
||||
<Icon name="branch" size="large" />
|
||||
<div class="am-setup-title">{setup().error ? "Workspace setup failed" : "Setting up workspace"}</div>
|
||||
<Show when={setup().branch}>
|
||||
<div class="am-setup-branch">{setup().branch}</div>
|
||||
</Show>
|
||||
<div class="am-setup-status">
|
||||
<Show when={!setup().error} fallback={<Icon name="circle-x" size="small" />}>
|
||||
<Spinner class="am-setup-spinner" />
|
||||
</Show>
|
||||
<span>{setup().message}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Show>
|
||||
{(() => {
|
||||
// Show setup overlay: either the transient ready/error state for the selected worktree,
|
||||
// or if the selected worktree is still being set up (from busyWorktrees map)
|
||||
const overlayState = () => {
|
||||
const s = setup()
|
||||
const sel = selection()
|
||||
// Transient ready/error overlay for the selected worktree (or worktree-less setup)
|
||||
if (s.active && (!s.worktreeId || sel === s.worktreeId)) return s
|
||||
// Persistent setup-in-progress for the currently selected worktree
|
||||
if (typeof sel === "string" && sel !== LOCAL) {
|
||||
const busy = busyWorktrees().get(sel)
|
||||
if (busy?.reason === "setting-up") {
|
||||
const wt = worktrees().find((w) => w.id === sel)
|
||||
return { active: true, message: busy.message, branch: busy.branch ?? wt?.branch }
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
return (
|
||||
<Show when={overlayState()}>
|
||||
{(state) => (
|
||||
<div class="am-setup-overlay">
|
||||
<div class="am-setup-card">
|
||||
<Icon name="branch" size="large" />
|
||||
<div class="am-setup-title">
|
||||
{state().error ? "Workspace setup failed" : "Setting up workspace"}
|
||||
</div>
|
||||
<Show when={state().branch}>
|
||||
<div class="am-setup-branch">{state().branch}</div>
|
||||
</Show>
|
||||
<div class="am-setup-status">
|
||||
<Show when={!state().error} fallback={<Icon name="circle-x" size="small" />}>
|
||||
<Spinner class="am-setup-spinner" />
|
||||
</Show>
|
||||
<span>{state().message}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</Show>
|
||||
)
|
||||
})()}
|
||||
<Show when={!contextEmpty()}>
|
||||
<div class="am-chat-wrapper">
|
||||
<ChatView
|
||||
@@ -1476,12 +1547,12 @@ const NewWorktreeDialog: Component<{ onClose: () => void }> = (props) => {
|
||||
<Dialog title="New Worktree" fit>
|
||||
<div class="am-nv-dialog" onKeyDown={handleKeyDown}>
|
||||
{/* Prompt input — reuses the same CSS as the sidebar chat input */}
|
||||
<div class="prompt-input-container">
|
||||
<div class="prompt-input-wrapper">
|
||||
<div class="prompt-input-ghost-wrapper">
|
||||
<div class="am-prompt-input-container">
|
||||
<div class="am-prompt-input-wrapper">
|
||||
<div class="am-prompt-input-ghost-wrapper">
|
||||
<textarea
|
||||
ref={textareaRef}
|
||||
class="prompt-input"
|
||||
class="am-prompt-input"
|
||||
placeholder={`Type a message (${isMac ? "\u2318" : "Ctrl+"}Enter to send)`}
|
||||
value={prompt()}
|
||||
onInput={(e) => {
|
||||
|
||||
@@ -763,8 +763,8 @@ button.am-section-toggle:hover .am-section-label {
|
||||
min-width: 460px;
|
||||
}
|
||||
|
||||
/* Reuse prompt-input-container inside dialog — resizable from bottom edge */
|
||||
.am-nv-dialog .prompt-input-container {
|
||||
/* Reuse am-prompt-input-container inside dialog — resizable from bottom edge */
|
||||
.am-nv-dialog .am-prompt-input-container {
|
||||
margin: 0;
|
||||
resize: vertical;
|
||||
overflow: hidden;
|
||||
@@ -774,16 +774,16 @@ button.am-section-toggle:hover .am-section-label {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.am-nv-dialog .prompt-input-wrapper {
|
||||
.am-nv-dialog .am-prompt-input-wrapper {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.am-nv-dialog .prompt-input-ghost-wrapper {
|
||||
.am-nv-dialog .am-prompt-input-ghost-wrapper {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.am-nv-dialog .prompt-input {
|
||||
.am-nv-dialog .am-prompt-input {
|
||||
color: var(--vscode-input-foreground, var(--text-base));
|
||||
resize: none;
|
||||
min-height: 100%;
|
||||
@@ -1027,6 +1027,17 @@ button.am-section-toggle:hover .am-section-label {
|
||||
}
|
||||
}
|
||||
|
||||
/* Not a git repo notice */
|
||||
|
||||
.am-not-git-notice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 10px;
|
||||
font-size: 12px;
|
||||
color: var(--text-weak);
|
||||
}
|
||||
|
||||
.am-skeleton-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, createSignal, createMemo, Switch, Match, onMount, onCleanup } from "solid-js"
|
||||
import { Component, createSignal, createMemo, Switch, Match, Show, onMount, onCleanup } from "solid-js"
|
||||
import { ThemeProvider } from "@kilocode/kilo-ui/theme"
|
||||
import { DialogProvider } from "@kilocode/kilo-ui/context/dialog"
|
||||
import { MarkedProvider } from "@kilocode/kilo-ui/context/marked"
|
||||
@@ -10,13 +10,14 @@ import { DataProvider } from "@kilocode/kilo-ui/context/data"
|
||||
import { Toast } from "@kilocode/kilo-ui/toast"
|
||||
import Settings from "./components/Settings"
|
||||
import ProfileView from "./components/ProfileView"
|
||||
import { VSCodeProvider } from "./context/vscode"
|
||||
import { VSCodeProvider, useVSCode } from "./context/vscode"
|
||||
import { ServerProvider, useServer } from "./context/server"
|
||||
import { ProviderProvider } from "./context/provider"
|
||||
import { ConfigProvider } from "./context/config"
|
||||
import { SessionProvider, useSession } from "./context/session"
|
||||
import { LanguageProvider } from "./context/language"
|
||||
import { ChatView } from "./components/chat"
|
||||
import { KiloNotifications } from "./components/chat/KiloNotifications"
|
||||
import SessionList from "./components/history/SessionList"
|
||||
import { NotificationsProvider } from "./context/notifications"
|
||||
import type { Message as SDKMessage, Part as SDKPart } from "@kilocode/sdk/v2"
|
||||
@@ -48,6 +49,7 @@ const DummyView: Component<{ title: string }> = (props) => {
|
||||
*/
|
||||
export const DataBridge: Component<{ children: any }> = (props) => {
|
||||
const session = useSession()
|
||||
const vscode = useVSCode()
|
||||
|
||||
const data = createMemo(() => {
|
||||
const id = session.currentSessionID()
|
||||
@@ -77,8 +79,12 @@ export const DataBridge: Component<{ children: any }> = (props) => {
|
||||
session.syncSession(sessionID)
|
||||
}
|
||||
|
||||
const open = (filePath: string, line?: number, column?: number) => {
|
||||
vscode.postMessage({ type: "openFile", filePath, line, column })
|
||||
}
|
||||
|
||||
return (
|
||||
<DataProvider data={data()} directory="" onPermissionRespond={respond} onSyncSession={sync}>
|
||||
<DataProvider data={data()} directory="" onPermissionRespond={respond} onSyncSession={sync} onOpenFile={open}>
|
||||
{props.children}
|
||||
</DataProvider>
|
||||
)
|
||||
@@ -149,6 +155,9 @@ const AppContent: Component = () => {
|
||||
<div class="container">
|
||||
<Switch fallback={<ChatView />}>
|
||||
<Match when={currentView() === "newTask"}>
|
||||
<Show when={!session.currentSessionID()}>
|
||||
<KiloNotifications />
|
||||
</Show>
|
||||
<ChatView onSelectSession={handleSelectSession} />
|
||||
</Match>
|
||||
<Match when={currentView() === "marketplace"}>
|
||||
|
||||
@@ -10,7 +10,6 @@ import { TaskHeader } from "./TaskHeader"
|
||||
import { MessageList } from "./MessageList"
|
||||
import { PromptInput } from "./PromptInput"
|
||||
import { QuestionDock } from "./QuestionDock"
|
||||
import { KiloNotifications } from "./KiloNotifications"
|
||||
import { useSession } from "../../context/session"
|
||||
import { useLanguage } from "../../context/language"
|
||||
|
||||
@@ -55,11 +54,10 @@ export const ChatView: Component<ChatViewProps> = (props) => {
|
||||
return (
|
||||
<div class="chat-view">
|
||||
<TaskHeader />
|
||||
<Show when={!id()}>
|
||||
<KiloNotifications />
|
||||
</Show>
|
||||
<div class="chat-messages">
|
||||
<MessageList onSelectSession={props.onSelectSession} />
|
||||
<div class="chat-messages-wrapper">
|
||||
<div class="chat-messages">
|
||||
<MessageList onSelectSession={props.onSelectSession} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Show when={!props.readonly}>
|
||||
@@ -99,6 +97,7 @@ export const ChatView: Component<ChatViewProps> = (props) => {
|
||||
{language.t("ui.permission.allowOnce")}
|
||||
</Button>
|
||||
</div>
|
||||
<p data-slot="permission-hint">{language.t("ui.permission.sessionHint")}</p>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -158,6 +158,12 @@ export const MessageList: Component<MessageListProps> = (props) => {
|
||||
return (
|
||||
<div class="message-list-container">
|
||||
<div ref={containerRef} class="message-list" role="log" aria-live="polite">
|
||||
<Show when={session.loading()}>
|
||||
<div class="message-list-loading" role="status">
|
||||
<Spinner />
|
||||
<span>{language.t("session.messages.loading")}</span>
|
||||
</div>
|
||||
</Show>
|
||||
<Show when={isEmpty()}>
|
||||
<div class="message-list-empty">
|
||||
<KiloLogo />
|
||||
@@ -177,8 +183,10 @@ export const MessageList: Component<MessageListProps> = (props) => {
|
||||
</Show>
|
||||
</div>
|
||||
</Show>
|
||||
<For each={messages()}>{(message) => <Message message={message} />}</For>
|
||||
<WorkingIndicator />
|
||||
<Show when={!session.loading()}>
|
||||
<For each={messages()}>{(message) => <Message message={message} />}</For>
|
||||
<WorkingIndicator />
|
||||
</Show>
|
||||
</div>
|
||||
|
||||
<Show when={showScrollButton()}>
|
||||
|
||||
@@ -13,6 +13,7 @@ import { useLanguage } from "../../context/language"
|
||||
import { useVSCode } from "../../context/vscode"
|
||||
import { ModelSelector } from "./ModelSelector"
|
||||
import { ModeSwitcher } from "./ModeSwitcher"
|
||||
import { ThinkingSelector } from "./ThinkingSelector"
|
||||
import { useFileMention } from "../../hooks/useFileMention"
|
||||
import { useImageAttachments } from "../../hooks/useImageAttachments"
|
||||
import { fileName, dirName, buildHighlightSegments } from "./prompt-input-utils"
|
||||
@@ -151,6 +152,17 @@ export const PromptInput: Component = () => {
|
||||
textareaRef.style.height = `${Math.min(textareaRef.scrollHeight, 200)}px`
|
||||
}
|
||||
|
||||
const handlePaste = (e: ClipboardEvent) => {
|
||||
imageAttach.handlePaste(e)
|
||||
// After pasting text, the textarea content changes but the layout may not
|
||||
// have reflowed yet, causing the caret position to be visually out of sync.
|
||||
// Defer height recalculation to after the browser completes the reflow.
|
||||
requestAnimationFrame(() => {
|
||||
adjustHeight()
|
||||
syncHighlightScroll()
|
||||
})
|
||||
}
|
||||
|
||||
const handleInput = (e: InputEvent) => {
|
||||
const target = e.target as HTMLTextAreaElement
|
||||
const val = target.value
|
||||
@@ -303,7 +315,7 @@ export const PromptInput: Component = () => {
|
||||
value={text()}
|
||||
onInput={handleInput}
|
||||
onKeyDown={handleKeyDown}
|
||||
onPaste={imageAttach.handlePaste}
|
||||
onPaste={handlePaste}
|
||||
onScroll={syncHighlightScroll}
|
||||
disabled={isDisabled()}
|
||||
rows={1}
|
||||
@@ -314,6 +326,7 @@ export const PromptInput: Component = () => {
|
||||
<div class="prompt-input-hint-selectors">
|
||||
<ModeSwitcher />
|
||||
<ModelSelector />
|
||||
<ThinkingSelector />
|
||||
</div>
|
||||
<div class="prompt-input-hint-actions">
|
||||
<Show
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
/**
|
||||
* ThinkingSelector component
|
||||
* Popover-based dropdown for choosing a thinking effort variant.
|
||||
* Only rendered when the selected model supports reasoning variants.
|
||||
*/
|
||||
|
||||
import { Component, createSignal, For, Show } from "solid-js"
|
||||
import { Popover } from "@kilocode/kilo-ui/popover"
|
||||
import { Button } from "@kilocode/kilo-ui/button"
|
||||
import { useSession } from "../../context/session"
|
||||
|
||||
export const ThinkingSelector: Component = () => {
|
||||
const session = useSession()
|
||||
const [open, setOpen] = createSignal(false)
|
||||
|
||||
const variants = () => session.variantList()
|
||||
const current = () => session.currentVariant()
|
||||
|
||||
function pick(value: string) {
|
||||
session.selectVariant(value)
|
||||
setOpen(false)
|
||||
}
|
||||
|
||||
const triggerLabel = () => {
|
||||
const v = current()
|
||||
return v ? v.charAt(0).toUpperCase() + v.slice(1) : ""
|
||||
}
|
||||
|
||||
return (
|
||||
<Show when={variants().length > 0}>
|
||||
<Popover
|
||||
placement="top-start"
|
||||
open={open()}
|
||||
onOpenChange={setOpen}
|
||||
triggerAs={Button}
|
||||
triggerProps={{ variant: "ghost", size: "small" }}
|
||||
trigger={
|
||||
<>
|
||||
<span class="thinking-selector-trigger-label">{triggerLabel()}</span>
|
||||
<svg width="10" height="10" viewBox="0 0 16 16" fill="currentColor" style={{ "flex-shrink": "0" }}>
|
||||
<path d="M8 4l4 5H4l4-5z" />
|
||||
</svg>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<div class="thinking-selector-list" role="listbox">
|
||||
<For each={variants()}>
|
||||
{(v) => (
|
||||
<div
|
||||
class={`thinking-selector-item${current() === v ? " selected" : ""}`}
|
||||
role="option"
|
||||
aria-selected={current() === v}
|
||||
onClick={() => pick(v)}
|
||||
>
|
||||
<span class="thinking-selector-item-name">{v.charAt(0).toUpperCase() + v.slice(1)}</span>
|
||||
</div>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</Popover>
|
||||
</Show>
|
||||
)
|
||||
}
|
||||
@@ -48,6 +48,7 @@ interface SessionStore {
|
||||
todos: Record<string, TodoItem[]> // sessionID -> todos
|
||||
modelSelections: Record<string, ModelSelection> // sessionID -> model
|
||||
agentSelections: Record<string, string> // sessionID -> agent name
|
||||
variantSelections: Record<string, string> // "providerID/modelID" -> variant name
|
||||
}
|
||||
|
||||
interface SessionContextValue {
|
||||
@@ -105,6 +106,11 @@ interface SessionContextValue {
|
||||
setSessionModel: (sessionID: string, providerID: string, modelID: string) => void
|
||||
setSessionAgent: (sessionID: string, name: string) => void
|
||||
|
||||
// Thinking variant for the selected model
|
||||
variantList: () => string[]
|
||||
currentVariant: () => string | undefined
|
||||
selectVariant: (value: string) => void
|
||||
|
||||
// Actions
|
||||
sendMessage: (text: string, providerID?: string, modelID?: string, files?: FileAttachment[]) => void
|
||||
abort: () => void
|
||||
@@ -177,6 +183,7 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
todos: {},
|
||||
modelSelections: {},
|
||||
agentSelections: {},
|
||||
variantSelections: {},
|
||||
})
|
||||
|
||||
// Keep pending selection in sync with provider default until the user
|
||||
@@ -268,6 +275,46 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
clearInterval(agentRetryTimer)
|
||||
})
|
||||
|
||||
// Variant (thinking effort) selection — keyed by "providerID/modelID"
|
||||
const variantKey = (sel: ModelSelection) => `${sel.providerID}/${sel.modelID}`
|
||||
|
||||
const variantList = () => {
|
||||
const sel = selected()
|
||||
if (!sel) return []
|
||||
const model = provider.findModel(sel)
|
||||
if (!model?.variants) return []
|
||||
return Object.keys(model.variants)
|
||||
}
|
||||
|
||||
const currentVariant = () => {
|
||||
const sel = selected()
|
||||
if (!sel) return undefined
|
||||
const list = variantList()
|
||||
if (list.length === 0) return undefined
|
||||
const stored = store.variantSelections[variantKey(sel)]
|
||||
return stored && list.includes(stored) ? stored : list[0]
|
||||
}
|
||||
|
||||
const selectVariant = (value: string) => {
|
||||
const sel = selected()
|
||||
if (!sel) return
|
||||
const key = variantKey(sel)
|
||||
setStore("variantSelections", key, value)
|
||||
vscode.postMessage({ type: "persistVariant", key, value })
|
||||
}
|
||||
|
||||
// Load persisted variants from extension globalState
|
||||
const unsubVariants = vscode.onMessage((message: ExtensionMessage) => {
|
||||
if (message.type !== "variantsLoaded") return
|
||||
for (const [k, v] of Object.entries(message.variants)) {
|
||||
setStore("variantSelections", k, v)
|
||||
}
|
||||
})
|
||||
|
||||
vscode.postMessage({ type: "requestVariants" })
|
||||
|
||||
onCleanup(unsubVariants)
|
||||
|
||||
// Handle messages from extension
|
||||
onMount(() => {
|
||||
const unsubscribe = vscode.onMessage((message: ExtensionMessage) => {
|
||||
@@ -325,7 +372,9 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
break
|
||||
|
||||
case "error":
|
||||
setLoading(false)
|
||||
// Only clear loading if the error is for the current session
|
||||
// (or has no sessionID for backwards compatibility)
|
||||
if (!message.sessionID || message.sessionID === currentSessionID()) setLoading(false)
|
||||
break
|
||||
}
|
||||
})
|
||||
@@ -629,6 +678,7 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
providerID,
|
||||
modelID,
|
||||
agent,
|
||||
variant: currentVariant(),
|
||||
files,
|
||||
})
|
||||
}
|
||||
@@ -864,6 +914,9 @@ export const SessionProvider: ParentComponent = (props) => {
|
||||
},
|
||||
allMessages,
|
||||
allParts,
|
||||
variantList,
|
||||
currentVariant,
|
||||
selectVariant,
|
||||
sendMessage,
|
||||
abort,
|
||||
compact,
|
||||
|
||||
@@ -7,15 +7,31 @@
|
||||
Chat View Layout
|
||||
============================================ */
|
||||
|
||||
.chat-view {
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chat-view {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-messages-wrapper {
|
||||
position: relative;
|
||||
flex: 1;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
.chat-messages {
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 0;
|
||||
}
|
||||
@@ -43,6 +59,17 @@
|
||||
gap: 12px;
|
||||
}
|
||||
|
||||
.message-list-loading {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: var(--vscode-descriptionForeground);
|
||||
gap: 12px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.message-list-empty {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -558,6 +585,42 @@
|
||||
letter-spacing: 0.03em;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Thinking Selector (uses kilo-ui Popover)
|
||||
============================================ */
|
||||
|
||||
.thinking-selector-trigger-label {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
|
||||
.thinking-selector-list {
|
||||
min-width: 120px;
|
||||
}
|
||||
|
||||
.thinking-selector-item {
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.thinking-selector-item:hover {
|
||||
background: var(--surface-interactive-hover, var(--vscode-list-hoverBackground));
|
||||
}
|
||||
|
||||
.thinking-selector-item.selected {
|
||||
background: var(
|
||||
--surface-interactive-active,
|
||||
var(--vscode-list-activeSelectionBackground, var(--vscode-list-hoverBackground))
|
||||
);
|
||||
}
|
||||
|
||||
.thinking-selector-item-name {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
Mode Switcher (uses kilo-ui Popover)
|
||||
============================================ */
|
||||
@@ -706,11 +769,26 @@
|
||||
============================================ */
|
||||
|
||||
.kilo-notifications {
|
||||
flex-shrink: 0;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
border-bottom: 1px solid var(--vscode-panel-border);
|
||||
animation: kilo-notifications-slide-in 0.3s ease-out;
|
||||
}
|
||||
|
||||
@keyframes kilo-notifications-slide-in {
|
||||
from {
|
||||
transform: translateY(-100%);
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.kilo-notifications-card {
|
||||
@@ -719,6 +797,7 @@
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.kilo-notifications-header {
|
||||
|
||||
@@ -215,6 +215,8 @@ export interface ProviderModel {
|
||||
latest?: boolean
|
||||
// Actual shape returned by the server (Provider.Model)
|
||||
limit?: { context: number; input?: number; output: number }
|
||||
variants?: Record<string, Record<string, unknown>>
|
||||
capabilities?: { reasoning: boolean }
|
||||
}
|
||||
|
||||
export interface Provider {
|
||||
@@ -334,6 +336,7 @@ export interface ErrorMessage {
|
||||
type: "error"
|
||||
message: string
|
||||
code?: string
|
||||
sessionID?: string
|
||||
}
|
||||
|
||||
export interface PartUpdatedMessage {
|
||||
@@ -554,6 +557,7 @@ export interface AgentManagerWorktreeSetupMessage {
|
||||
message: string
|
||||
sessionId?: string
|
||||
branch?: string
|
||||
worktreeId?: string
|
||||
}
|
||||
|
||||
// Agent Manager worktree state types (mirrored from WorktreeStateManager)
|
||||
@@ -587,6 +591,7 @@ export interface AgentManagerStateMessage {
|
||||
sessions: ManagedSessionState[]
|
||||
tabOrder?: Record<string, string[]>
|
||||
sessionsCollapsed?: boolean
|
||||
isGitRepo?: boolean
|
||||
}
|
||||
|
||||
// Resolved keybindings for agent manager actions
|
||||
@@ -604,6 +609,12 @@ export interface AgentManagerMultiVersionProgressMessage {
|
||||
groupId?: string
|
||||
}
|
||||
|
||||
// Stored variant selections loaded from extension globalState (extension → webview)
|
||||
export interface VariantsLoadedMessage {
|
||||
type: "variantsLoaded"
|
||||
variants: Record<string, string>
|
||||
}
|
||||
|
||||
// Request webview to send initial prompt to a newly created session (extension → webview)
|
||||
export interface AgentManagerSendInitialMessage {
|
||||
type: "agentManager.sendInitialMessage"
|
||||
@@ -660,6 +671,7 @@ export type ExtensionMessage =
|
||||
| AgentManagerSendInitialMessage
|
||||
| SetChatBoxMessage
|
||||
| TriggerTaskMessage
|
||||
| VariantsLoadedMessage
|
||||
|
||||
// ============================================
|
||||
// Messages FROM webview TO extension
|
||||
@@ -677,6 +689,7 @@ export interface SendMessageRequest {
|
||||
providerID?: string
|
||||
modelID?: string
|
||||
agent?: string
|
||||
variant?: string
|
||||
files?: FileAttachment[]
|
||||
}
|
||||
|
||||
@@ -726,6 +739,13 @@ export interface OpenExternalRequest {
|
||||
url: string
|
||||
}
|
||||
|
||||
export interface OpenFileRequest {
|
||||
type: "openFile"
|
||||
filePath: string
|
||||
line?: number
|
||||
column?: number
|
||||
}
|
||||
|
||||
export interface CancelLoginRequest {
|
||||
type: "cancelLogin"
|
||||
}
|
||||
@@ -937,6 +957,18 @@ export interface SetSessionsCollapsedRequest {
|
||||
collapsed: boolean
|
||||
}
|
||||
|
||||
// Variant persistence (webview → extension)
|
||||
export interface PersistVariantRequest {
|
||||
type: "persistVariant"
|
||||
key: string
|
||||
value: string
|
||||
}
|
||||
|
||||
// Request stored variants from extension (webview → extension)
|
||||
export interface RequestVariantsMessage {
|
||||
type: "requestVariants"
|
||||
}
|
||||
|
||||
export type WebviewMessage =
|
||||
| SendMessageRequest
|
||||
| AbortRequest
|
||||
@@ -949,6 +981,7 @@ export type WebviewMessage =
|
||||
| LogoutRequest
|
||||
| RefreshProfileRequest
|
||||
| OpenExternalRequest
|
||||
| OpenFileRequest
|
||||
| CancelLoginRequest
|
||||
| SetOrganizationRequest
|
||||
| WebviewReadyRequest
|
||||
@@ -988,6 +1021,8 @@ export type WebviewMessage =
|
||||
| CreateMultiVersionRequest
|
||||
| SetTabOrderRequest
|
||||
| SetSessionsCollapsedRequest
|
||||
| PersistVariantRequest
|
||||
| RequestVariantsMessage
|
||||
|
||||
// ============================================
|
||||
// VS Code API type
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"name": "@kilocode/cli",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -2,6 +2,7 @@ import { Server } from "../../server/server"
|
||||
import { cmd } from "./cmd"
|
||||
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import { Instance } from "../../project/instance" // kilocode_change
|
||||
|
||||
export const ServeCommand = cmd({
|
||||
command: "serve",
|
||||
@@ -14,7 +15,20 @@ export const ServeCommand = cmd({
|
||||
const opts = await resolveNetworkOptions(args)
|
||||
const server = Server.listen(opts)
|
||||
console.log(`kilo server listening on http://${server.hostname}:${server.port}`) // kilocode_change
|
||||
await new Promise(() => {})
|
||||
await server.stop()
|
||||
// kilocode_change start - graceful signal shutdown
|
||||
const abort = new AbortController()
|
||||
const shutdown = async () => {
|
||||
try {
|
||||
await Instance.disposeAll()
|
||||
await server.stop(true)
|
||||
} finally {
|
||||
abort.abort()
|
||||
}
|
||||
}
|
||||
process.on("SIGTERM", shutdown)
|
||||
process.on("SIGINT", shutdown)
|
||||
process.on("SIGHUP", shutdown)
|
||||
await new Promise((resolve) => abort.signal.addEventListener("abort", resolve))
|
||||
// kilocode_change end
|
||||
},
|
||||
})
|
||||
|
||||
@@ -127,6 +127,13 @@ export const TuiThreadCommand = cmd({
|
||||
process.on("SIGUSR2", async () => {
|
||||
await client.call("reload", undefined)
|
||||
})
|
||||
// kilocode_change start - graceful shutdown on external signals
|
||||
const shutdown = async () => {
|
||||
await client.call("shutdown", undefined).catch(() => {})
|
||||
}
|
||||
process.on("SIGHUP", shutdown)
|
||||
process.on("SIGTERM", shutdown)
|
||||
// kilocode_change end
|
||||
|
||||
const prompt = await iife(async () => {
|
||||
const piped = !process.stdin.isTTY ? await Bun.stdin.text() : undefined
|
||||
|
||||
@@ -3,6 +3,7 @@ import { UI } from "../ui"
|
||||
import { cmd } from "./cmd"
|
||||
import { withNetworkOptions, resolveNetworkOptions } from "../network"
|
||||
import { Flag } from "../../flag/flag"
|
||||
import { Instance } from "../../project/instance" // kilocode_change
|
||||
import open from "open"
|
||||
import { networkInterfaces } from "os"
|
||||
|
||||
@@ -75,7 +76,20 @@ export const WebCommand = cmd({
|
||||
open(displayUrl).catch(() => {})
|
||||
}
|
||||
|
||||
await new Promise(() => {})
|
||||
await server.stop()
|
||||
// kilocode_change start - graceful signal shutdown
|
||||
const abort = new AbortController()
|
||||
const shutdown = async () => {
|
||||
try {
|
||||
await Instance.disposeAll()
|
||||
await server.stop(true)
|
||||
} finally {
|
||||
abort.abort()
|
||||
}
|
||||
}
|
||||
process.on("SIGTERM", shutdown)
|
||||
process.on("SIGINT", shutdown)
|
||||
process.on("SIGHUP", shutdown)
|
||||
await new Promise((resolve) => abort.signal.addEventListener("abort", resolve))
|
||||
// kilocode_change end
|
||||
},
|
||||
})
|
||||
|
||||
@@ -26,8 +26,9 @@ import { EOL } from "os"
|
||||
import { WebCommand } from "./cli/cmd/web"
|
||||
import { PrCommand } from "./cli/cmd/pr"
|
||||
import { SessionCommand } from "./cli/cmd/session"
|
||||
// kilocode_change start - Import telemetry and legacy migration
|
||||
// kilocode_change start - Import telemetry, instance disposal, and legacy migration
|
||||
import { Telemetry } from "@kilocode/kilo-telemetry"
|
||||
import { Instance } from "./project/instance" // kilocode_change
|
||||
import { migrateLegacyKiloAuth, ENV_FEATURE } from "@kilocode/kilo-gateway"
|
||||
|
||||
// kilocode_change - set feature for tracking. 'serve' is spawned by other services
|
||||
@@ -197,6 +198,8 @@ try {
|
||||
await Telemetry.shutdown()
|
||||
// kilocode_change end
|
||||
|
||||
await Instance.disposeAll() // kilocode_change - safety net disposal (no-op if already disposed)
|
||||
|
||||
// Some subprocesses don't react properly to SIGTERM and similar signals.
|
||||
// Most notably, some docker-container-based MCP servers don't handle such signals unless
|
||||
// run using `docker run --init`.
|
||||
|
||||
@@ -8,3 +8,4 @@ Usage notes:
|
||||
- When `custom` is enabled (default), a "Type your own answer" option is added automatically; don't include "Other" or catch-all options
|
||||
- Answers are returned as arrays of labels; set `multiple: true` to allow selecting more than one
|
||||
- If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label
|
||||
- Header must be 30 characters or less (maxLength: 30)
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/package.json",
|
||||
"name": "@kilocode/plugin",
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"type": "module",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"version": "1.0.24",
|
||||
"version": "1.0.25",
|
||||
"dependencies": {},
|
||||
"peerDependencies": {}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user