Merge branch 'main' into kevinvandijk/kilo-opencode-v1.2.15

This commit is contained in:
Kevin van Dijk
2026-03-02 22:25:30 +01:00
committed by GitHub
437 changed files with 10466 additions and 3774 deletions
+6
View File
@@ -0,0 +1,6 @@
# Git LFS tracking for binary/media files
*.gif filter=lfs diff=lfs merge=lfs -text
*.mp4 filter=lfs diff=lfs merge=lfs -text
# Visual regression baseline snapshots
packages/kilo-ui/tests/**/*.png filter=lfs diff=lfs merge=lfs -text
+4
View File
@@ -50,6 +50,7 @@ jobs:
./script/version.ts
env:
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
KILO_BUMP: ${{ inputs.bump }}
KILO_VERSION: ${{ inputs.version }}
KILO_API_KEY: ${{ secrets.KILO_API_KEY }}
@@ -78,6 +79,7 @@ jobs:
KILO_VERSION: ${{ needs.version.outputs.version }}
KILO_RELEASE: ${{ needs.version.outputs.release }}
GH_TOKEN: ${{ github.token }}
GH_REPO: ${{ github.repository }}
- uses: actions/upload-artifact@v4
with:
@@ -115,6 +117,7 @@ jobs:
env:
CLI_DIST_DIR: ../../packages/opencode/dist
KILO_VERSION: ${{ needs.build-cli.outputs.version }}
GH_REPO: ${{ github.repository }}
- uses: actions/upload-artifact@v4
with:
@@ -312,6 +315,7 @@ jobs:
env:
KILO_VERSION: ${{ needs.version.outputs.version }}
KILO_RELEASE: ${{ needs.version.outputs.release }}
GH_REPO: ${{ github.repository }}
AUR_KEY: ${{ secrets.AUR_KEY }}
GITHUB_TOKEN: ${{ steps.committer.outputs.token }}
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
+4
View File
@@ -6,9 +6,13 @@ on:
- dev
paths:
- "packages/kilo-vscode/**"
- "packages/ui/**"
- "packages/kilo-ui/**"
pull_request:
paths:
- "packages/kilo-vscode/**"
- "packages/ui/**"
- "packages/kilo-ui/**"
workflow_dispatch:
jobs:
+2 -3
View File
@@ -39,6 +39,8 @@ jobs:
run: bun turbo test
e2e:
# kilocode_change - disabled: packages/app is not actively maintained
if: false
name: e2e (${{ matrix.settings.name }})
needs: unit
strategy:
@@ -98,12 +100,9 @@ jobs:
runs-on: blacksmith-4vcpu-ubuntu-2404
needs:
- unit
- e2e
if: always()
steps:
- name: Verify upstream test jobs passed
run: |
echo "unit=${{ needs.unit.result }}"
echo "e2e=${{ needs.e2e.result }}"
test "${{ needs.unit.result }}" = "success"
test "${{ needs.e2e.result }}" = "success"
+103
View File
@@ -0,0 +1,103 @@
name: Visual Regression Tests
on:
pull_request:
paths:
- "packages/kilo-ui/**"
- "packages/ui/**"
- "packages/util/**"
- "packages/sdk/js/**"
- ".github/workflows/visual-regression.yml"
jobs:
visual-regression:
name: Visual Regression (kilo-ui)
runs-on: blacksmith-4vcpu-ubuntu-2404
timeout-minutes: 15
steps:
- name: Checkout
uses: actions/checkout@v4
with:
lfs: true
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.head_ref }}
- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest
- name: Cache Bun modules
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: bun-${{ hashFiles('bun.lock') }}
- name: Install dependencies
run: bun install
- name: Cache Playwright browsers
id: playwright-cache
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: playwright-${{ hashFiles('packages/kilo-ui/package.json') }}
- name: Install Playwright browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: bunx playwright install chromium
working-directory: packages/kilo-ui
- name: Install Playwright system deps
run: bunx playwright install-deps chromium
working-directory: packages/kilo-ui
- name: Cache Storybook build
id: storybook-cache
uses: actions/cache@v4
with:
path: packages/kilo-ui/storybook-static
key: storybook-${{ hashFiles('packages/kilo-ui/src/**', 'packages/kilo-ui/.storybook/**', 'packages/ui/src/**', 'packages/kilo-ui/package.json') }}
- name: Build Storybook
if: steps.storybook-cache.outputs.cache-hit != 'true'
run: bun run build-storybook
working-directory: packages/kilo-ui
- name: Generate baselines for new/missing stories
run: bun run test:visual:update
working-directory: packages/kilo-ui
env:
CI: true
PLAYWRIGHT_WORKERS: "4"
- name: Commit and push new baselines (if any)
id: commit-baselines
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add packages/kilo-ui/tests/visual-regression.spec.ts-snapshots/
if git diff --cached --quiet; then
echo "No new baselines — nothing to commit."
echo "changed=false" >> "$GITHUB_OUTPUT"
else
git commit -m "chore: update visual regression baselines"
git lfs push --all origin
git push
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Fail if baselines changed
if: steps.commit-baselines.outputs.changed == 'true'
run: |
echo "::error::Visual regression baselines changed. New baselines have been committed to the branch. Please pull and review."
exit 1
- name: Upload test results on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: visual-regression-results
path: packages/kilo-ui/test-results/
retention-days: 7
+4 -6
View File
@@ -36,12 +36,10 @@ Server mode is opt-in only. When enabled, set `KILO_SERVER_PASSWORD` to require
# Reporting Security Issues
We appreciate your efforts to responsibly disclose your findings, and will make every effort to acknowledge your contributions.
We value the contributions of the security research community and recognize the importance of a coordinated approach to vulnerability disclosure. If you have discovered a security vulnerability, we encourage you to let us know immediately. We welcome the opportunity to work with you to resolve the issue promptly.
To report a security issue, please use the GitHub Security Advisory ["Report a Vulnerability"](https://github.com/Kilo-Org/kilocode/security/advisories/new) tab.
Please email your findings to [security@kilo.ai](mailto:security@kilo.ai). We will acknowledge your report and work with you to resolve the issue.
The team will send a response indicating the next steps in handling your report. After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
After the initial reply to your report, the security team will keep you informed of the progress towards a fix and full announcement, and may ask for additional information or guidance.
## Escalation
If you do not receive an acknowledgement of your report within 6 business days, you may send an email to hi@kilo.ai
For more details, see our [Security Disclosure](https://kilo.ai/security) page.
+602 -32
View File
File diff suppressed because it is too large Load Diff
+2 -1
View File
@@ -162,7 +162,8 @@
unzip
gnutar
gzip
ripgrep
patchelf
ripgrep
kilo-dev
kilo-install-bin
kilo-bin
+4 -4
View File
@@ -1,8 +1,8 @@
{
"nodeModules": {
"x86_64-linux": "sha256-SfRknqil91nThVGfFqgRw3cNhVpXj5eQWFsaQEuAG3U=",
"aarch64-linux": "sha256-AajOQ51MXotJjEhj2W2fsyrsuzQv1EnAgsd3tBUC6rY=",
"aarch64-darwin": "sha256-CtlmtoOQHSwCIWCsW9flazk/J9FYKVns3glu1AtYr/w=",
"x86_64-darwin": "sha256-QcFljmUfdYpBQyPd87+mML5F98Vi/bbAMyeSxA1noec="
"x86_64-linux": "sha256-nK6w/+ZFZ1e3IF3JQaCdE7mn7FtEuY5fUAJNOiPjTVM=",
"aarch64-linux": "sha256-oOiCU3mNgccNrU3VQydTozb5PhRAmUnoyetDkePakq0=",
"aarch64-darwin": "sha256-qT4DC6mGD2pkNjSX2RJ6+FCRIlDnXEYiHAxurULkgXI=",
"x86_64-darwin": "sha256-4Lew/qSnYVbaJlfP+9fIi2mTuw4mMLYNkFbPNQkJu9k="
}
}
+1 -1
View File
@@ -107,6 +107,6 @@
"@openrouter/ai-sdk-provider@1.5.4": "patches/@openrouter%2Fai-sdk-provider@1.5.4.patch",
"ghostty-web@0.3.0": "patches/ghostty-web@0.3.0.patch"
},
"version": "7.0.30",
"version": "7.0.33",
"peerDependencies": {}
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { createOpencodeClient } from "@kilocode/sdk/v2/client"
import { createKiloClient } from "@kilocode/sdk/v2/client"
import { base64Encode } from "@opencode-ai/util/encode"
export const serverHost = process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"
@@ -11,7 +11,7 @@ export const modKey = process.platform === "darwin" ? "Meta" : "Control"
export const terminalToggleKey = "Control+Backquote"
export function createSdk(directory?: string) {
return createOpencodeClient({ baseUrl: serverUrl, directory, throwOnError: true })
return createKiloClient({ baseUrl: serverUrl, directory, throwOnError: true })
}
export async function getWorktree() {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/app",
"version": "7.0.30",
"version": "7.0.33",
"description": "",
"type": "module",
"exports": {
@@ -42,10 +42,8 @@ beforeAll(async () => {
useParams: () => ({}),
}))
// kilocode_change start
mock.module("@kilocode/sdk/v2/client", () => ({
// kilocode_change end
createOpencodeClient: (input: { directory: string }) => {
createKiloClient: (input: { directory: string }) => {
createdClients.push(input.directory)
return clientFor(input.directory)
},
+2 -2
View File
@@ -1,6 +1,6 @@
import type {
Config,
OpencodeClient,
KiloClient,
Path,
Project,
ProviderAuthResponse,
@@ -59,7 +59,7 @@ function createGlobalSync() {
const owner = getOwner()
if (!owner) throw new Error("GlobalSync must be created within owner")
const sdkCache = new Map<string, OpencodeClient>()
const sdkCache = new Map<string, KiloClient>()
const booting = new Map<string, Promise<void>>()
const sessionLoads = new Map<string, Promise<void>>()
const sessionMeta = new Map<string, { limit: number }>()
@@ -1,6 +1,6 @@
import type {
Config,
OpencodeClient,
KiloClient,
Path,
PermissionRequest,
Project,
@@ -32,7 +32,7 @@ type GlobalStore = {
}
export async function bootstrapGlobal(input: {
globalSDK: OpencodeClient
globalSDK: KiloClient
connectErrorTitle: string
connectErrorDescription: string
requestFailedTitle: string
@@ -111,7 +111,7 @@ function groupBySession<T extends { id: string; sessionID: string }>(input: T[])
export async function bootstrapDirectory(input: {
directory: string
sdk: OpencodeClient
sdk: KiloClient
store: Store<State>
setStore: SetStoreFunction<State>
vcsCache: VcsCache
+1 -2
View File
@@ -134,8 +134,7 @@ export const dict = {
"provider.connect.oauth.code.invalid": "رمز التفويض غير صالح",
"provider.connect.oauth.auto.visit.prefix": "قم بزيارة ",
"provider.connect.oauth.auto.visit.link": "هذا الرابط",
"provider.connect.oauth.auto.visit.suffix":
" وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.",
"provider.connect.oauth.auto.visit.suffix": " وأدخل الرمز أدناه لتوصيل حسابك واستخدام نماذج {{provider}} في Kilo.",
"provider.connect.oauth.auto.confirmationCode": "رمز التأكيد",
"provider.connect.toast.connected.title": "تم توصيل {{provider}}",
"provider.connect.toast.connected.description": "نماذج {{provider}} متاحة الآن للاستخدام.",
+2 -4
View File
@@ -389,8 +389,7 @@ export const dict = {
"toast.session.unshare.failed.description": "Une erreur s'est produite lors de l'annulation du partage de la session",
"toast.session.listFailed.title": "Échec du chargement des sessions pour {{project}}",
"toast.update.title": "Mise à jour disponible",
"toast.update.description":
"Une nouvelle version d'Kilo ({{version}}) est maintenant disponible pour installation.",
"toast.update.description": "Une nouvelle version d'Kilo ({{version}}) est maintenant disponible pour installation.",
"toast.update.action.installRestart": "Installer et redémarrer",
"toast.update.action.notYet": "Pas encore",
"error.page.title": "Quelque chose s'est mal passé",
@@ -524,8 +523,7 @@ export const dict = {
"sidebar.workspaces.enable": "Activer les espaces de travail",
"sidebar.workspaces.disable": "Désactiver les espaces de travail",
"sidebar.gettingStarted.title": "Commencer",
"sidebar.gettingStarted.line1":
"Kilo inclut des modèles gratuits pour que vous puissiez commencer immédiatement.",
"sidebar.gettingStarted.line1": "Kilo inclut des modèles gratuits pour que vous puissiez commencer immédiatement.",
"sidebar.gettingStarted.line2":
"Connectez n'importe quel fournisseur pour utiliser des modèles, y compris Claude, GPT, Gemini etc.",
"sidebar.project.recentSessions": "Sessions récentes",
+1 -2
View File
@@ -146,8 +146,7 @@ export const dict = {
"provider.connect.oauth.code.invalid": "รหัสการอนุญาตไม่ถูกต้อง",
"provider.connect.oauth.auto.visit.prefix": "เยี่ยมชม ",
"provider.connect.oauth.auto.visit.link": "ลิงก์นี้",
"provider.connect.oauth.auto.visit.suffix":
" และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo",
"provider.connect.oauth.auto.visit.suffix": " และป้อนรหัสด้านล่างเพื่อเชื่อมต่อบัญชีและใช้โมเดล {{provider}} ใน Kilo",
"provider.connect.oauth.auto.confirmationCode": "รหัสยืนยัน",
"provider.connect.toast.connected.title": "{{provider}} ที่เชื่อมต่อแล้ว",
"provider.connect.toast.connected.description": "โมเดล {{provider}} พร้อมใช้งานแล้ว",
+1 -2
View File
@@ -147,8 +147,7 @@ export const dict = {
"provider.connect.oauth.code.invalid": "授權碼無效",
"provider.connect.oauth.auto.visit.prefix": "造訪 ",
"provider.connect.oauth.auto.visit.link": "此連結",
"provider.connect.oauth.auto.visit.suffix":
" 並輸入以下程式碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。",
"provider.connect.oauth.auto.visit.suffix": " 並輸入以下程式碼,以連線你的帳戶並在 Kilo 中使用 {{provider}} 模型。",
"provider.connect.oauth.auto.confirmationCode": "確認碼",
"provider.connect.toast.connected.title": "{{provider}} 已連線",
"provider.connect.toast.connected.description": "現在可以使用 {{provider}} 模型了。",
+7 -2
View File
@@ -1075,13 +1075,18 @@ export default function Layout(props: ParentProps) {
}
function projectRoot(directory: string) {
const key = workspaceKey(directory)
const project = layout.projects
.list()
.find((item) => item.worktree === directory || item.sandboxes?.includes(directory))
.find(
(item) =>
workspaceKey(item.worktree) === key ||
(item.sandboxes ?? []).some((sandbox) => workspaceKey(sandbox) === key),
)
if (project) return project.worktree
const known = Object.entries(store.workspaceOrder).find(
([root, dirs]) => root === directory || dirs.includes(directory),
([root, dirs]) => workspaceKey(root) === key || dirs.some((dir) => workspaceKey(dir) === key),
)
if (known) return known[0]
@@ -32,9 +32,7 @@ export const ProjectIcon = (props: { project: LocalProject; class?: string; noti
<div class="size-full rounded overflow-clip">
<Avatar
fallback={name()}
src={
props.project.id === KILO_PROJECT_ID ? "https://kilo.ai/favicon.svg" : props.project.icon?.override
}
src={props.project.id === KILO_PROJECT_ID ? "https://kilo.ai/favicon.svg" : props.project.icon?.override}
{...getAvatarColors(props.project.icon?.color)}
class="size-full rounded"
classList={{ "badge-mask": unseenCount() > 0 && props.notify }}
+3 -3
View File
@@ -1,10 +1,10 @@
import { createOpencodeClient } from "@kilocode/sdk/v2/client"
import { createKiloClient } from "@kilocode/sdk/v2/client"
import type { ServerConnection } from "@/context/server"
export function createSdkForServer({
server,
...config
}: Omit<NonNullable<Parameters<typeof createOpencodeClient>[0]>, "baseUrl"> & {
}: Omit<NonNullable<Parameters<typeof createKiloClient>[0]>, "baseUrl"> & {
server: ServerConnection.HttpBase
}) {
const auth = (() => {
@@ -14,7 +14,7 @@ export function createSdkForServer({
}
})()
return createOpencodeClient({
return createKiloClient({
...config,
headers: { ...config.headers, ...auth },
baseUrl: server.url,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/desktop",
"private": true,
"version": "7.0.30",
"version": "7.0.33",
"type": "module",
"license": "MIT",
"scripts": {
+6 -6
View File
@@ -1,7 +1,7 @@
id = "kilo"
name = "Kilo"
description = "The open source coding agent."
version = "7.0.30"
version = "7.0.33"
schema_version = 1
authors = ["Anomaly"]
repository = "https://github.com/Kilo-Org/kilocode"
@@ -11,26 +11,26 @@ name = "Kilo"
icon = "./icons/opencode.svg"
[agent_servers.opencode.targets.darwin-aarch64]
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.30/opencode-darwin-arm64.zip"
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.33/opencode-darwin-arm64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.darwin-x86_64]
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.30/opencode-darwin-x64.zip"
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.33/opencode-darwin-x64.zip"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-aarch64]
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.30/opencode-linux-arm64.tar.gz"
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.33/opencode-linux-arm64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.linux-x86_64]
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.30/opencode-linux-x64.tar.gz"
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.33/opencode-linux-x64.tar.gz"
cmd = "./opencode"
args = ["acp"]
[agent_servers.opencode.targets.windows-x86_64]
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.30/opencode-windows-x64.zip"
archive = "https://github.com/Kilo-Org/kilocode/releases/download/v7.0.33/opencode-windows-x64.zip"
cmd = "./opencode.exe"
args = ["acp"]
+75 -1
View File
@@ -3,14 +3,84 @@ import Prism from "prismjs"
import * as React from "react"
import { Codicon } from "./Codicon"
let mermaidInitialized = false
function MermaidBlock({ children }) {
const ref = React.useRef(null)
const [svg, setSvg] = React.useState("")
const [error, setError] = React.useState(false)
React.useEffect(() => {
const code = typeof children === "string" ? children : ref.current?.textContent || ""
if (!code.trim()) return
const id = `mermaid-${Math.random().toString(36).slice(2, 9)}`
import("mermaid").then((mod) => {
const mermaid = mod.default
if (!mermaidInitialized) {
mermaid.initialize({
startOnLoad: false,
theme: "base",
themeVariables: {
primaryColor: "#33332d",
primaryTextColor: "#e9e9e9",
primaryBorderColor: "#555",
lineColor: "#a3a3a2",
secondaryColor: "#2a2a24",
tertiaryColor: "#1a1a18",
background: "#1a1a18",
mainBkg: "#33332d",
nodeBorder: "#555",
clusterBkg: "#2a2a24",
clusterBorder: "#444",
titleColor: "#e9e9e9",
edgeLabelBackground: "#1a1a18",
},
securityLevel: "strict",
fontFamily: "inherit",
})
mermaidInitialized = true
}
mermaid
.render(id, code.trim())
.then(({ svg }) => setSvg(svg))
.catch((err) => {
console.error(err)
setError(true)
})
})
}, [children])
if (error) {
return <pre className="language-mermaid">{children}</pre>
}
if (svg) {
return (
<div
className="mermaid-diagram"
dangerouslySetInnerHTML={{ __html: svg }}
style={{ display: "flex", justifyContent: "center", padding: "1rem 0" }}
/>
)
}
return (
<pre ref={ref} style={{ visibility: "hidden", height: 0, overflow: "hidden" }}>
{children}
</pre>
)
}
export function CodeBlock({ children, "data-language": language }) {
const ref = React.useRef(null)
const timeoutRef = React.useRef(null)
const [copied, setCopied] = React.useState(false)
React.useEffect(() => {
if (language === "mermaid") return
if (ref.current) Prism.highlightElement(ref.current, false)
}, [children])
}, [children, language])
React.useEffect(() => {
return () => {
@@ -20,6 +90,10 @@ export function CodeBlock({ children, "data-language": language }) {
}
}, [])
if (language === "mermaid") {
return <MermaidBlock>{children}</MermaidBlock>
}
const handleCopy = async () => {
const code = ref.current?.textContent || ""
try {
+32 -5
View File
@@ -1,4 +1,4 @@
import React, { useState, Children, isValidElement, ReactNode, ReactElement } from "react"
import React, { useState, useEffect, Children, isValidElement, ReactNode, ReactElement } from "react"
interface TabProps {
label: string
@@ -9,21 +9,48 @@ interface TabsProps {
children: ReactNode
}
function slugify(label: string) {
return label
.toLowerCase()
.replace(/\s+/g, "-")
.replace(/[^a-z0-9-]/g, "")
}
export function Tab({ children }: TabProps) {
return <>{children}</>
}
export function Tabs({ children }: TabsProps) {
const [activeIndex, setActiveIndex] = useState(0)
const tabs = Children.toArray(children).filter(
(child): child is ReactElement<TabProps> =>
isValidElement(child) && (child.type === Tab || (child.props as any)?.label !== undefined),
)
const indexFromHash = () => {
if (typeof window === "undefined") return 0
const hash = window.location.hash.slice(1)
if (!hash) return 0
const found = tabs.findIndex((tab) => slugify(tab.props.label) === hash)
return found >= 0 ? found : 0
}
const [activeIndex, setActiveIndex] = useState(indexFromHash)
useEffect(() => {
const onHashChange = () => setActiveIndex(indexFromHash())
window.addEventListener("hashchange", onHashChange)
return () => window.removeEventListener("hashchange", onHashChange)
}, [])
const selectTab = (index: number) => {
setActiveIndex(index)
const slug = slugify(tabs[index].props.label)
history.replaceState(null, "", `#${slug}`)
}
return (
<div className="tabs-container my-6 border border-neutral-300 dark:border-neutral-700 rounded-lg overflow-hidden">
<div className="tabs-header flex border-b border-neutral-300 dark:border-neutral-700 bg-neutral-100 dark:bg-neutral-800/50 overflow-x-auto">
<div className="tabs-header flex border-b border-neutral-300 dark:border-neutral-700 bg-neutral-100 dark:bg-neutral-800/50 overflow-x-auto scrollbar-none touch-pan-x">
{tabs.map((tab, index) => (
<button
key={index}
@@ -32,7 +59,7 @@ export function Tabs({ children }: TabsProps) {
? "bg-white dark:bg-neutral-900 text-yellow-800 dark:text-yellow-300 border-b-2 border-yellow-800 dark:border-yellow-300 -mb-[1px]"
: "text-neutral-600 dark:text-neutral-400 hover:text-neutral-900 dark:hover:text-neutral-200 hover:bg-neutral-200 dark:hover:bg-neutral-700/50"
}`}
onClick={() => setActiveIndex(index)}
onClick={() => selectTab(index)}
>
{tab.props.label}
</button>
+18 -1
View File
@@ -16,7 +16,24 @@ export const AutomateNav: NavSection[] = [
],
},
{ href: "/automate/agent-manager", children: "Agent Manager" },
{ href: "/automate/kiloclaw", children: "KiloClaw" },
{
href: "/automate/kiloclaw/overview",
children: "KiloClaw",
subLinks: [
{ href: "/automate/kiloclaw/overview", children: "Overview" },
{ href: "/automate/kiloclaw/dashboard", children: "Dashboard" },
{ href: "/automate/kiloclaw/control-ui", children: "Control UI" },
{
href: "/automate/kiloclaw/chat-platforms",
children: "Chat Platforms",
},
{
href: "/automate/kiloclaw/troubleshooting",
children: "Troubleshooting",
},
{ href: "/automate/kiloclaw/pricing", children: "Pricing" },
],
},
],
},
{
+3 -1
View File
@@ -25,5 +25,7 @@ exclude = [
'^https?://(cloud|console)\.google\.ai',
'https://opencode.ai/pages/config',
'^localhost:3000/',
'https://tbench.ai/'
'https://tbench.ai/',
# GitHub URLs cause persistent HTTP/2 protocol errors when checked from GitHub Actions runners
'^https?://github\.com/',
]
+2 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@kilocode/kilo-docs",
"version": "7.0.30",
"version": "7.0.33",
"private": true,
"scripts": {
"dev": "next dev --webpack --port 3002",
@@ -15,6 +15,7 @@
"@markdoc/next.js": "^0.5.0",
"js-yaml": "^4.1.0",
"@vscode/codicons": "^0.0.44",
"mermaid": "11.12.3",
"next": "^16.1.5",
"posthog-js": "^1.335.3",
"prismjs": "^1.30.0",
+13 -2
View File
@@ -1,8 +1,19 @@
import React from "react"
import React, { useState, useEffect } from "react"
import Link from "next/link"
import Head from "next/head"
const subtitles = [
"The page you requested does not exist or has been moved.",
"That link is dead, and may have ridden off into the sunset on a pink pony 🦄",
]
export default function Custom404() {
const [subtitle, setSubtitle] = useState("")
useEffect(() => {
setSubtitle(subtitles[Math.floor(Math.random() * subtitles.length)])
}, [])
return (
<>
<Head>
@@ -39,7 +50,7 @@ export default function Custom404() {
{/* Message */}
<div className="message-section">
<h1 className="message-title">Page not found</h1>
<p className="message-subtitle">The page you requested does not exist or has been moved.</p>
{subtitle && <p className="message-subtitle">{subtitle}</p>}
</div>
{/* Actions */}
+8 -7
View File
@@ -137,13 +137,14 @@ export default function MyApp({ Component, pageProps }: AppProps<MyAppProps>) {
<meta name="referrer" content="strict-origin" />
<meta name="title" content={title} />
<meta name="description" content={description} />
<link rel="shortcut icon" href="https://kilo.ai/favicon.ico" />
<link rel="icon" href="https://kilo.ai/favicon.ico" sizes="48x48" type="image/x-icon" />
<link rel="icon" href="https://kilo.ai/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="https://kilo.ai/apple-touch-icon.png" sizes="180x180" type="image/png" />
<link rel="manifest" href="https://kilo.ai/site.webmanifest" />
<link rel="icon" href="https://kilo.ai/android-chrome-192x192.png" type="image/png" sizes="192x192" />
<link rel="icon" href="https://kilo.ai/android-chrome-512x512.png" type="image/png" sizes="512x512" />
<link rel="icon" href="/docs/favicon/favicon.ico" sizes="48x48" type="image/x-icon" />
<link rel="shortcut icon" href="/docs/favicon/favicon.ico" />
<link rel="icon" href="/docs/favicon/favicon.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/docs/favicon/apple-touch-icon.png" sizes="180x180" type="image/png" />
<link rel="icon" href="/docs/favicon/android-chrome-192x192.png" sizes="192x192" type="image/png" />
<link rel="icon" href="/docs/favicon/android-chrome-512x512.png" sizes="512x512" type="image/png" />
<link rel="manifest" href="/docs/site.webmanifest" />
<meta name="apple-mobile-web-app-title" content="Kilo Code" />
<meta name="theme-color" content="#617A91" />
{/* Preconnect to Algolia for better performance */}
<link rel="preconnect" href="https://PMZUYBQDAK-dsn.algolia.net" crossOrigin="anonymous" />
@@ -17,15 +17,7 @@ Kilo's Code Reviews integrate with GitHub via a **GitHub App** to automatically
### Step 1: Install the GitHub App
1. Go to the **Integrations** page:
- **Personal**: [app.kilo.ai/integrations/github](https://app.kilo.ai/integrations/github)
- **Organization**: Your organization → Integrations → GitHub
2. Click **Install GitHub App**
3. Choose which GitHub account or organization to install the app on
4. Select repository access:
- **All repositories** — the app can access all current and future repos
- **Only select repositories** — choose specific repos
5. Click **Install**
Connect your GitHub account via the [Integrations page](/docs/automate/integrations#connecting-github). Once connected, return here to configure the Review Agent.
The GitHub App requests the following permissions:
@@ -21,48 +21,9 @@ Both **GitLab.com** and **self-hosted GitLab instances** are supported.
### Step 1: Connect GitLab
You can connect using **OAuth** or a **Personal Access Token (PAT)**. Choose the method that matches your GitLab setup:
Connect your GitLab account via the [Integrations page](/docs/automate/integrations#connecting-gitlab). You can use **OAuth** (GitLab.com or self-hosted) or a **Personal Access Token (PAT)**.
{% tabs %}
{% tab label="OAuth (GitLab.com)" %}
1. Go to the **Integrations** page:
- **Personal**: [app.kilo.ai/integrations/gitlab](https://app.kilo.ai/integrations/gitlab)
- **Organization**: Your organization → Integrations → GitLab
2. Click **Connect GitLab**
3. Authorize the application on GitLab
4. You'll be redirected back to Kilo with the connection active
{% /tab %}
{% tab label="OAuth (Self-Hosted)" %}
For self-hosted GitLab instances using OAuth, you need to register an OAuth application first:
1. In your GitLab instance, go to **Admin Area → Applications** (or **User Settings → Applications**)
2. Create a new application:
- **Name**: `Kilo Code`
- **Redirect URI**: `https://app.kilo.ai/api/integrations/gitlab/callback`
- **Scopes**: `api`, `read_user`, `read_repository`, `write_repository`
- **Confidential**: Yes
3. Copy the **Application ID** and **Secret**
4. In Kilo, go to the GitLab integration page
5. Enter your **Instance URL**, **Client ID**, and **Client Secret**
6. Click **Connect** and authorize
{% /tab %}
{% tab label="Personal Access Token" %}
1. In GitLab, go to **User Settings → Access Tokens**
2. Create a token with the `api` scope
3. Copy the token
4. In Kilo, go to the GitLab integration page
5. Paste the token (and enter your Instance URL for self-hosted)
6. Click **Connect**
> PAT tokens cannot be refreshed automatically. When your token expires, create a new one in GitLab and reconnect in Kilo.
{% /tab %}
{% /tabs %}
Once connected, return here to configure the Review Agent.
### Step 2: Configure the Review Agent
@@ -26,7 +26,7 @@ Kilo's **Code Reviews** feature automatically analyzes your pull or merge reques
Before enabling Code Reviews:
- **A platform integration must be configured:** Connect your GitHub or GitLab account via the [Integrations page](https://app.kilo.ai/integrations) so that the Review Agent can access your repositories.
- **A platform integration must be configured:** Connect your GitHub or GitLab account via the [Integrations page](https://app.kilo.ai/integrations) so that the Review Agent can access your repositories. See the [Integration setup guide](/docs/automate/integrations) for detailed instructions.
- **Kilo Code credits:** The AI model uses credits when analyzing your code.
## Cost
+115 -18
View File
@@ -5,32 +5,42 @@ description: "Overview of Kilo Code integrations"
# Kilo Code Integrations
Kilo Integrations lets you connect your GitHub account (and soon, GitLab and Bitbucket) to enable advanced features inside Kilo Code. Once connected, Kilo can access your repositories securely through the **KiloConnect** GitHub App, enabling features like **Cloud Agents** and **Kilo Deploy**.
Kilo Integrations lets you connect your GitHub or GitLab account (soon Bitbucket) to enable advanced features inside Kilo Code. Once connected, Kilo can access your repositories securely, enabling features like **Code Reviews**, **Cloud Agents**, and **Kilo Deploy**.
## Supported Platforms
| Platform | Integration Type | Details |
| -------- | ---------------- | --------------------------------- |
| GitHub | GitHub App | [GitHub Setup](#connecting-github)|
| GitLab | OAuth or PAT | [GitLab Setup](#connecting-gitlab)|
## What You Can Do With Integrations
- **Connect GitHub to Kilo Code** in a few clicks
- **Authorize the KiloConnect App** for repo access
- **Enable advanced features** like Cloud Agents and Kilo Deploy
- **Connect GitHub or GitLab to Kilo Code** in a few clicks
- **Enable advanced features** like Cloud Agents, Code Reviews, and Kilo Deploy
- **Authorize repository access** so Kilo can analyze and work with your code
## Prerequisites
Before connecting:
- You must have a **GitHub account**.
- You need permission to install GitHub Apps for the repositories you want Kilo to access.
- (Optional) If you're connecting an organization, you must be an **org admin** or have app installation permissions.
- You must have a **GitHub** or **GitLab** account.
- For GitHub: You need permission to install GitHub Apps for the repositories you want Kilo to access.
- For GitLab: You need **Maintainer** role (or higher) on the projects you want to connect.
- (Optional) If you're connecting an organization, you must be an admin or have app installation permissions.
## Connecting GitHub to Kilo
---
## Connecting GitHub
### 1. Open the Integrations Page
Go to your **Personal** or **Organization Dashboard**, and navigate to the [Integrations](https://app.kilo.ai/integrations) tab
Go to your **Personal** or **Organization Dashboard**, and navigate to the [Integrations](https://app.kilo.ai/integrations) tab.
### 2. Start the Connection Flow
1. Click **Configure** on the GitHub panel.
2. Youll be redirected to GitHub to authorize the **KiloConnect** App.
2. You'll be redirected to GitHub to authorize the **KiloConnect** App.
3. Select the GitHub account or organization you want to connect.
### 3. Choose Repository Access
@@ -46,13 +56,62 @@ Click **Install & Authorize** to continue.
Once approved:
- Youll return to the Kilo Integrations page.
- Github will show a **Connected** status.
- You'll return to the Kilo Integrations page.
- GitHub will show a **Connected** status.
- Your Kilo workspace can now access GitHub repositories securely.
---
## Connecting GitLab
You can connect GitLab using **OAuth** or a **Personal Access Token (PAT)**. Both **GitLab.com** and **self-hosted GitLab instances** are supported.
{% tabs %}
{% tab label="OAuth (GitLab.com)" %}
1. Go to the **Integrations** page:
- **Personal**: [app.kilo.ai/integrations/gitlab](https://app.kilo.ai/integrations/gitlab)
- **Organization**: Your organization → Integrations → GitLab
2. Click **Connect GitLab**
3. Authorize the application on GitLab
4. You'll be redirected back to Kilo with the connection active
{% /tab %}
{% tab label="OAuth (Self-Hosted)" %}
For self-hosted GitLab instances using OAuth, you need to register an OAuth application first:
1. In your GitLab instance, go to **Admin Area → Applications** (or **User Settings → Applications**)
2. Create a new application:
- **Name**: `Kilo Code`
- **Redirect URI**: `https://app.kilo.ai/api/integrations/gitlab/callback`
- **Scopes**: `api`, `read_user`, `read_repository`, `write_repository`
- **Confidential**: Yes
3. Copy the **Application ID** and **Secret**
4. In Kilo, go to the GitLab integration page
5. Enter your **Instance URL**, **Client ID**, and **Client Secret**
6. Click **Connect** and authorize
{% /tab %}
{% tab label="Personal Access Token" %}
1. In GitLab, go to **User Settings → Access Tokens**
2. Create a token with the `api` scope
3. Copy the token
4. In Kilo, go to the GitLab integration page
5. Paste the token (and enter your Instance URL for self-hosted)
6. Click **Connect**
> PAT tokens cannot be refreshed automatically. When your token expires, create a new one in GitLab and reconnect in Kilo.
{% /tab %}
{% /tabs %}
---
## What Happens After Connecting
Once GitHub is connected, the following features will be enabled in Kilo:
Once your Git provider is connected, the following features are enabled in Kilo:
### Cloud Agents
@@ -60,6 +119,12 @@ Once GitHub is connected, the following features will be enabled in Kilo:
- Auto-create branches and push work continuously
- Work from anywhere while keeping your repo in sync
### Code Reviews
- Automated AI review on every pull request or merge request
- Consistent feedback based on your team's standards
- See the [Code Reviews guide](/docs/automate/code-reviews/overview) for setup
### Kilo Deploy
- Deploy Next.js 14 & 15 apps directly from Kilo
@@ -68,29 +133,61 @@ Once GitHub is connected, the following features will be enabled in Kilo:
### Upcoming:
- **GitLab Integration**
- **Bitbucket Integration**
---
## Managing or Removing the Integration
From the same **Integrations** page, you can click "Manage on Github" to:
### GitHub
From the **Integrations** page, click "Manage on GitHub" to:
- View the GitHub account you connected
- Update which repositories Kilo has access to
- Disconnect GitHub entirely
- Reauthorize the app if permissions change
### GitLab
From the **Integrations** page:
- Click **Disconnect** to remove the GitLab connection
- Your tokens are cleared, but webhook configuration is preserved so reconnecting restores your setup
> Disconnecting from Kilo does not revoke OAuth tokens on GitLab's side. You can manually revoke them from **GitLab → User Settings → Applications → Authorized Applications**.
---
## Troubleshooting
**“I dont see my repositories.”**
### GitHub
**"I don't see my repositories."**
Ensure the KiloConnect App is installed for the correct GitHub org and that repo access includes the repositories you need.
**My organization blocks third-party apps.**
**"My organization blocks third-party apps."**
You may need an admin to approve installing GitHub Apps.
**Cloud Agents or Deploy cant access my repo.**
**"Cloud Agents or Deploy can't access my repo."**
Revisit the GitHub app settings and confirm the app has the correct repo scope.
### GitLab
**"No projects listed after connecting."**
Click the refresh button to sync projects from GitLab. Ensure your GitLab account has access to the projects you expect.
**"Permission denied" errors.**
You need **Maintainer role** on the GitLab project for webhook and bot token creation.
**"Token expired."**
- **OAuth**: Tokens refresh automatically. If refresh fails, reconnect from the integration page.
- **PAT**: Create a new token in GitLab and reconnect in Kilo.
**"Self-hosted connection issues."**
- Verify your instance URL is accessible from the internet
- Ensure HTTPS is configured
- Check that OAuth application scopes include all required scopes
- Verify the redirect URI matches: `https://app.kilo.ai/api/integrations/gitlab/callback`
@@ -0,0 +1,76 @@
---
title: "Connecting Chat Platforms"
description: "Connect your KiloClaw agent to Telegram, Discord, Slack, and more"
---
# Connecting Chat Platforms
KiloClaw supports connecting your AI agent to Telegram, Discord, and Slack. You can configure channels from the **Settings** tab on your [KiloClaw dashboard](/docs/automate/kiloclaw/dashboard#channels), or from the OpenClaw Control UI after accessing your instance.
## Supported Platforms
### Telegram
To connect Telegram, you need a **Bot Token** from [@BotFather](https://t.me/BotFather) on Telegram.
Enter the token in the Settings tab and click **Save**. You can remove or replace a configured token at any time.
{% image src="/docs/img/kiloclaw/telegram.png" alt="Connect account screen" width="800" caption="Telegram bot token entry" /%}
Advanced settings such as DM policy, allow lists, and groups can be configured in the OpenClaw Control UI after connecting.
### Discord
To connect Discord, you need a **Bot Token** from the [Discord Developer Portal](https://discord.com/developers/applications).
{% image src="/docs/img/kiloclaw/discord.png" alt="Connect account screen" width="800" caption="Discord bot token entry" /%}
Enter the token in the Settings tab and click **Save**. You can remove or replace a configured token at any time.
### Slack
To connect Slack, you need **both** of the following tokens from [Slack App Management](https://api.slack.com/apps):
- **Bot Token** — starts with `xoxb-`
- **App Token** — starts with `xapp-`
{% image src="/docs/img/kiloclaw/slack.png" alt="Connect account screen" width="800" caption="Slack bot and app token entry" /%}
Both tokens are required — you cannot save with only one.
## Configuring a Channel
1. Open your [KiloClaw dashboard](/docs/automate/kiloclaw/dashboard)
2. Go to the **Settings** tab
3. Scroll to the **Channels** section
4. Enter the required token(s) for your platform
5. Click **Save**
{% callout type="info" %}
After saving channel tokens, you need to **Redeploy** or **Restart OpenClaw** for the changes to take effect.
{% /callout %}
To remove a channel, clear its token(s) in Settings and save. Redeploy or Restart OpenClaw afterward to apply the removal.
## Pairing Requests
After connecting a channel and starting your instance, new users and devices need to be approved before they can interact with your agent.
- **Channel pairing** — When someone messages your bot on Telegram, Discord, or Slack for the first time, a pairing request appears on your dashboard. You need to click **Approve** to allow them to use the bot.
- **Device pairing** — When a new browser or device connects to the OpenClaw Control UI, a similar request appears. Click **Approve** to authorize it.
{% callout type="note" %}
Pairing data is cached for about 2 minutes. Use the refresh button to check for new requests.
{% /callout %}
## Future Support
Additional platforms (such as WhatsApp) are planned for future releases. For the latest on supported platforms, refer to the [OpenClaw documentation](https://docs.openclaw.ai).
## Related
- [KiloClaw Overview](/docs/automate/kiloclaw/overview)
- [Dashboard Reference](/docs/automate/kiloclaw/dashboard)
- [Troubleshooting](/docs/automate/kiloclaw/troubleshooting)
- [KiloClaw Pricing](/docs/automate/kiloclaw/pricing)
- [OpenClaw Documentation](https://docs.openclaw.ai)
@@ -0,0 +1,102 @@
---
title: "OpenClaw Control UI"
description: "Browser-based dashboard for managing your OpenClaw instance"
---
# OpenClaw Control UI
The Control UI is a browser-based dashboard (built with Vite + Lit) served by the OpenClaw Gateway on the same port as the gateway itself (default: `http://localhost:18789/`). It connects via WebSocket and gives you real-time control over your agent, channels, sessions, and system configuration. For KiloClaw users, see [Accessing the Control UI](/docs/automate/kiloclaw/dashboard#accessing-the-control-ui) to get started.
## Features
- **Chat** — Send messages, stream responses with live tool-call output, view history, and abort runs.
- **Channels** — View the status of connected messaging platforms, scan QR codes for login, and edit per-channel config.
- **Sessions** — List active sessions with thinking and verbose overrides.
- **Cron Jobs** — Create, edit, enable/disable, run, and view history of scheduled tasks.
- **Skills** — View status, enable/disable, install, and manage API keys for skills.
- **Nodes** — List paired devices and their capabilities.
- **Exec Approvals** — Edit gateway or node command allowlists. See [Exec Approvals](#exec-approvals) below.
- **Config** — View and edit `openclaw.json` with schema-based form rendering and a raw JSON editor.
- **Logs** — Live tail of gateway logs with filtering and export.
- **Debug** — Status, health, model snapshots, event log, and manual RPC calls.
- **Update** — Run package updates and restart the gateway.
For more details, please see the official [OpenClaw documentation](https://docs.openclaw.ai/web/control-ui).
{% callout type="warning" %}
Do not use the **Update** feature in the Control UI to update KiloClaw. Use **Redeploy** from the [KiloClaw Dashboard](/docs/automate/kiloclaw/dashboard#redeploy) instead. Updating via the Control UI will not apply the correct KiloClaw platform image and may break your instance.
{% /callout %}
## Authentication
Auth is handled via token or password on the WebSocket handshake. We use the one time "access code" from your KiloClaw Dashboard to pair your device. Other remote connections require one-time device pairing — the pairing request appears on the [KiloClaw Dashboard](/docs/automate/kiloclaw/dashboard#pairing-requests) or in the Control UI itself.
## Exec Approvals
Exec approvals are the safety interlock that controls which commands your agent can run on the host machine (gateway or node). By default, **all host exec requests are denied** — you must explicitly allowlist the commands you want your agent to run independently. This prevents accidental execution of destructive commands.
{% callout type="warning" %}
The default security policy is `deny`. You must configure an allowlist before your agent can execute any host commands.
{% /callout %}
### How It Works
Approvals are enforced locally on the execution host and sit on top of tool policy and elevated gating. The effective policy is always the **stricter** of `tools.exec.*` and the approvals defaults. Settings are stored in `~/.openclaw/exec-approvals.json` on the host.
### Security Policies
| Policy | Behavior |
| ----------- | ---------------------------------------------- |
| `deny` | Block all host exec requests (default) |
| `allowlist` | Allow only commands matching the allowlist |
| `full` | Allow everything (equivalent to elevated mode) |
### Ask Behavior
The `ask` setting controls when the user is prompted for approval:
| Setting | Behavior |
| --------- | ------------------------------------------------------- |
| `off` | Never prompt |
| `on-miss` | Prompt only when the allowlist does not match (default) |
| `always` | Prompt on every command |
If a prompt is required but no UI is reachable, the `askFallback` setting decides the outcome (`deny` by default).
### Allowlists
Allowlists are **per agent** — each agent has its own set of allowed command patterns. Patterns are case-insensitive globs that must resolve to binary paths (basename-only entries are ignored).
Example patterns:
```
~/Projects/**/bin/rg
~/.local/bin/*
/opt/homebrew/bin/rg
```
Each entry tracks last-used metadata (timestamp, command, resolved path) so you can audit and keep the list tidy.
### Approval Flow
When a command requires approval, the gateway broadcasts the request to connected operator clients. The approval dialog shows the command, arguments, working directory, agent ID, and resolved path. You can:
- **Allow once** — run the command now
- **Allow always** — add to the allowlist and run
- **Deny** — block the request
Approval prompts can also be forwarded to chat channels (Slack, Telegram, Discord, etc.) and resolved with `/approve`.
### Editing in the Control UI
Navigate to **Nodes > Exec Approvals** in the Control UI to edit defaults, per-agent overrides, and allowlists. Select a scope (Defaults or a specific agent), adjust the policy, add or remove allowlist patterns, then save.
{% callout type="info" %}
If a node does not yet advertise exec approval capabilities, edit its `~/.openclaw/exec-approvals.json` file directly. You can also use the CLI: `openclaw approvals`.
{% /callout %}
## Related
- [KiloClaw Dashboard](/docs/automate/kiloclaw/dashboard)
- [KiloClaw Overview](/docs/automate/kiloclaw/overview)
- [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms)
@@ -0,0 +1,162 @@
---
title: "KiloClaw Dashboard Reference"
description: "Managing your KiloClaw instance from the dashboard"
---
# KiloClaw Dashboard
This page covers everything you can do from the KiloClaw dashboard. For getting started, see [KiloClaw Overview](/docs/automate/kiloclaw/overview).
{% image src="/docs/img/kiloclaw/dashboard.png" alt="Connect account screen" width="800" caption="The KiloClaw Dashboard" /%}
## Instance Status
Your instance is always in one of these states as indicated by the status label at the top of your dashboard:
| Status | Label | Meaning |
| --------------- | --------------- | ------------------------------------------------------------- |
| **Running** | Machine Online | Your agent is online and reachable |
| **Stopped** | Machine Stopped | The machine is off, but all your files and data are preserved |
| **Provisioned** | Provisioned | Your instance has been created but never started |
| **Destroying** | Destroying | The instance is being permanently deleted |
## Instance Controls
There are four actions you can take on your instance. Which ones are available depends on the current status.
### ▶️ Start Machine
Boots your instance. If this is the first time starting after provisioning, the machine is created; otherwise, the existing machine resumes. Can take up to 60 seconds.
Available when the instance is **stopped** or **provisioned**.
### 🔄 Restart OpenClaw
Restarts just the OpenClaw process without rebooting the machine. This is a quick way to recover from a process-level issue — active sessions will briefly disconnect and reconnect automatically.
Available when the instance is **running**.
### ↩️ Redeploy
Stops the machine, applies your current configuration (environment variables, secrets, channel tokens), and starts it again. When redeploying, you have two options:
- **Redeploy** — Redeploys using the same platform version your instance was originally set up with. Use this when you only need to apply configuration changes without changing the underlying platform.
- **Upgrade & Redeploy** — Upgrades your instance to the latest supported platform version, then redeploys. Use this to pick up new features and fixes from the changelog.
**Your files, git repos, cron jobs, and everything on your persistent volume are preserved.** Redeploy is not a factory reset — think of it as "apply config and restart" (or "upgrade and restart" if you choose **Upgrade & Redeploy**).
You should redeploy when:
- The changelog shows "Redeploy Required" or "Redeploy Suggested" (use **Upgrade & Redeploy**)
- You've changed channel tokens or secrets in Settings (use **Redeploy**)
- You want to pick up the latest platform updates (use **Upgrade & Redeploy**)
Available when the instance is **running**.
### 🩺 OpenClaw Doctor
Runs diagnostics and automatically fixes common configuration issues. This is the recommended first step when something isn't working. Output is shown in real time.
Available when the instance is **running**.
## Gateway Process
The Gateway Process tab shows the health of the OpenClaw process running inside your machine:
- **State** — Whether the process is Running, Stopped, Starting, Stopping, Crashed, or Shutting Down
- **Uptime** — How long it's been running since the last start
- **Restarts** — How many times the process has been automatically restarted
- **Last Exit** — The exit code and timestamp from the last time the process stopped or crashed
If the gateway crashes, it's automatically restarted. The machine itself can be running even when the gateway process is down — they're independent.
{% callout type="note" %}
Gateway process info is only available when the machine is running.
{% /callout %}
## Settings
### Changing the Model
Select a model from the dropdown and click **Save & Provision**. The API key is platform-managed and refreshes automatically when you save — you never need to enter one. The key has a 30-day expiry.
### Channels
You can connect Telegram, Discord, and Slack by entering bot tokens in the Settings tab. See [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms) for setup instructions.
{% callout type="info" %}
After saving channel tokens, you need to **Redeploy** or **Restart OpenClaw** for the changes to take effect.
{% /callout %}
### Stop, Destroy & Restore
At the bottom of Settings:
- **Stop Instance** — Shuts down the machine. All your data is preserved and you can start it again later.
- **Destroy Instance** — Permanently deletes your instance and all its data, including files, configuration, and workspace. This cannot be undone.
- **Restore Config** — Restores your original `openclaw.json` in your instance. The existing `openclaw.json` is backed up to `/root/.openclaw` before the restore takes place.
## Accessing the Control UI
When your instance is running you can access the [OpenClaw Control UI](/docs/automate/kiloclaw/control-ui) — a browser-based dashboard for managing your agent, channels, sessions, exec approvals, and more:
1. Click **Access Code** to generate a one-time code (expires in 10 minutes)
2. Click **Open** to launch the OpenClaw web interface in a new tab
3. Enter the access code to authenticate
See the [Control UI reference](/docs/automate/kiloclaw/control-ui) for a full overview of its capabilities.
{% callout type="warning" %}
Do not use the **Update** feature in the OpenClaw Control UI to update KiloClaw. Use **Redeploy** from the KiloClaw Dashboard instead. Updating via the Control UI will not apply the correct KiloClaw platform image and may break your instance.
{% /callout %}
## Pairing Requests
When your instance is running, the dashboard shows any pending pairing requests. These appear when:
- Someone messages your bot on Telegram, Discord, or Slack for the first time
- A new browser or device connects to the Control UI
You need to **approve** each request before the user or device can interact with your agent. See [Pairing Requests](/docs/automate/kiloclaw/chat-platforms#pairing-requests) for details.
## Changelog
The dashboard shows recent KiloClaw platform updates. Each entry is tagged as a **feature** or **bugfix**, and some include a deploy hint:
- **Redeploy Required** — You must redeploy for this change to take effect on your instance
- **Redeploy Suggested** — Redeploying is recommended but not strictly necessary
## Instance Lifecycle
| Action | What Happens | Data Preserved? |
| ---------------------- | --------------------------------------------------------------------------- | --------------- |
| **Create & Provision** | Allocates storage in the best region available and saves your config. | N/A |
| **Start Machine** | Boots the machine and starts OpenClaw. | Yes |
| **Stop Instance** | Shuts down the machine. | Yes |
| **Restart OpenClaw** | Restarts the OpenClaw process. Machine stays up. | Yes |
| **Redeploy** | Stops, applies config, and restarts the machine (same version or upgraded). | Yes |
| **Destroy Instance** | Permanently deletes everything. | No |
## Machine Specs
Each instance runs on a dedicated machine — there is no shared infrastructure between users.
| Spec | Value |
| ------- | -------------------- |
| CPU | 2 shared vCPUs |
| Memory | 3 GB RAM |
| Storage | 10 GB persistent SSD |
Your storage is region-pinned — once your instance is created in a region (e.g., DFW), it always runs there. OpenClaw config lives at `/root/.openclaw` and the workspace at `/root/clawd`.
{% callout type="info" %}
These are the beta specifications for machines and subject to change without notice.
{% /callout %}
## Related
- [KiloClaw Overview](/docs/automate/kiloclaw/overview)
- [OpenClaw Control UI](/docs/automate/kiloclaw/control-ui)
- [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms)
- [Troubleshooting](/docs/automate/kiloclaw/troubleshooting)
- [KiloClaw Pricing](/docs/automate/kiloclaw/pricing)
@@ -5,20 +5,21 @@ description: "One-click deployment of your personal AI agent with OpenClaw"
# KiloClaw 🦀
KiloClaw is Kilo's hosted [OpenClaw](https://openclaw.ai) servicea one-click deployment that gives you a personal AI agent without the complexity of self-hosting. OpenClaw is an open source AI agent that connects to chat platforms like WhatsApp, Telegram, and Discord.
KiloClaw is Kilo's hosted [OpenClaw](https://openclaw.ai) servicea one-click deployment that gives you a personal AI agent without the complexity of self-hosting. OpenClaw is an open source AI agent that connects to chat platforms like Telegram, Discord, and Slack.
KiloClaw is powered by KiloCode. The API key is platform-managed, so you never need to bring your own. KiloClaw is currently in **Beta**.
## Why KiloClaw?
- **No infrastructure setup** — Skip Docker, servers, and configuration files
- **Instant provisioning** — Your agent is ready in seconds
- **Powered by KiloCode** — API key is automatically generated and refreshed
- **Uses existing credits** — Runs on your Kilo Gateway balance
- **Multiple free models** — Choose from several models at no additional cost
- **Web UI included** — Access your agent's web interface from the instance dashboard
- **Web UI included** — Access your agent's web interface directly from the dashboard
## Prerequisites
Before creating an instance:
- **Kilo account** — Sign up at [kilo.ai](https://kilo.ai) if you haven't already
- **Gateway credits** — KiloClaw uses your existing [Gateway credits](/docs/gateway/usage-and-billing) for model inference
@@ -34,92 +35,55 @@ Before creating an instance:
{% image src="/docs/img/kiloclaw/create-instance.png" alt="Create instance modal with model selection" width="600" caption="Model selection during instance creation" /%}
5. Click **Create & Provision**
5. Optionally configure chat channels (Telegram, Discord, Slack) — you can also do this later from [Settings](/docs/automate/kiloclaw/dashboard#settings)
6. Click **Create & Provision**
Your instance will be provisioned and ready within seconds.
Your instance will be provisioned in seconds. Each instance runs on a dedicated machine with 2 shared vCPUs, 3 GB RAM, and a 10 GB persistent SSD. Once created in a region, your instance always runs there.
## Managing Your Instance
Once created, you can control your instance from the dashboard.
The KiloClaw dashboard gives you full control over your instance.
{% image src="/docs/img/kiloclaw/instance-dashboard.png" alt="Instance dashboard with controls and status" width="800" caption="Instance management dashboard" /%}
### Instance Controls
### Controls
- **Start** — Boot up a stopped instance
- **Stop** — Shut down the instance (preserves configuration)
- **Restart**Stop and start the instance
- **Start Machine** — Boot a stopped instance (up to 60 seconds)
- **Restart OpenClaw** — Quick restart of just the OpenClaw process; the machine stays up
- **Redeploy**This will stop the machine, apply any pending image or config updates, and restart it. The machine will be briefly offline.
- **OpenClaw Doctor** — Run diagnostics and auto-fix common issues
### Dashboard Tabs
| Tab | Purpose |
| ------------ | ----------------------------------------------- |
| **Overview** | Instance status, uptime, and resource usage |
| **Settings** | Model configuration and instance parameters |
| **Actions** | Quick actions and connected platform management |
For full details on each control and when to use them, see the [Dashboard Reference](/docs/automate/kiloclaw/dashboard).
### Changelog
Your instance page includes a changelog with recent KiloClaw platform updates.
The dashboard shows recent platform updates. Some updates include a deploy hint — either **Redeploy Required** or **Redeploy Suggested** — to let you know when to redeploy your instance.
Each changelog entry is labeled by update type:
### Pairing Requests
- **Feature** — New capability or enhancement
- **Bug** — Fix for incorrect or broken behavior
Some entries also include a redeploy label:
- **Redeploy required** — You must redeploy your instance to fully take advantage of the change
- **Redeploy suggested** — Redeploy is optional and only needed if you want to use the new behavior
For example, if you manually configured a channel such as Telegram, and would prefer to have KiloClaw manage the channel for you, you would need to redeploy.
When you initialize a new channel for the first time, or a new device connects to the Control UI, you'll see a pairing request on the dashboard that you need to approve. See [Pairing Requests](/docs/automate/kiloclaw/chat-platforms#pairing-requests) for details.
## Accessing Your Agent
To connect to your agent's web interface:
1. Click **Get Access Code** from your instance dashboard
2. Copy the one-time access code (expires in 10 minutes)
1. Click **Access Code** to get a one-time code (expires in 10 minutes)
{% image src="/docs/img/kiloclaw/access-code-modal.png" alt="Access code modal showing one-time code" width="500" caption="One-time access code with 10-minute expiration" /%}
3. Click the **Open Claw** button in the top-right corner of your instance dashboard
4. Enter your access code to authenticate
2. Click **Open** to launch the OpenClaw web interface
3. Enter your access code to authenticate
{% image src="/docs/img/kiloclaw/openclaw-dashboard.png" alt="OpenClaw web interface" width="800" caption="OpenClaw web UI" /%}
## Connecting Chat Platforms
OpenClaw supports integration with popular messaging platforms:
- WhatsApp
- Telegram
- Discord
- Slack
- And more
For platform-specific setup instructions, refer to the [OpenClaw documentation](https://docs.openclaw.ai).
## Using your OpenClaw Agent
OpenClaw lets you customize your own AI assistant that can actually take action — check your email, manage your calendar, control smart devices, browse the web, and message you on Telegram or Discord when something needs attention. It's like having a personal assistant that runs 24/7, with the skills and access you choose to give it.
For more information on use cases for OpenClaw, see:
For more information on use cases:
- [OpenClaw Showcase](https://docs.openclaw.ai/start/showcase)
- [100 hours of OpenClaw in 35 Minutes](https://www.youtube.com/watch?v=_kZCoW-Qxnc)
- [Clawhub](https://clawhub.ai/): search for skills
## Pricing
KiloClaw uses your existing Kilo Gateway credits—there's no separate billing or subscription:
- **Instance hosting** — Free for 7 days during beta
- **Model inference** — Charged against your Gateway credit balance
- **Free models** — Several models are available at no cost. See the [Kilo Leaderboard](https://kilo.ai/leaderboard#all-models) for current availability.
See [Gateway Usage and Billing](/docs/gateway/usage-and-billing) for credit pricing details.
## Limitations
KiloClaw is currently in **beta**. Current constraints include:
@@ -135,6 +99,10 @@ Have feedback or running into issues? Join the [Kilo Discord](https://kilo.ai/di
## Related
- [Dashboard Reference](/docs/automate/kiloclaw/dashboard)
- [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms)
- [Troubleshooting](/docs/automate/kiloclaw/troubleshooting)
- [KiloClaw Pricing](/docs/automate/kiloclaw/pricing)
- [Gateway Usage and Billing](/docs/gateway/usage-and-billing)
- [Agent Manager](/docs/automate/agent-manager)
- [OpenClaw Documentation](https://docs.openclaw.ai)
@@ -0,0 +1,20 @@
---
title: "KiloClaw Pricing"
description: "Pricing details for KiloClaw instances and model inference"
---
# KiloClaw Pricing
KiloClaw uses your existing Kilo Gateway credits—there's no separate billing or subscription:
- **Instance hosting** — Free for 7 days during beta
- **Model inference** — Charged against your Gateway credit balance
- **Free models** — Several models are available at no cost. See the [Kilo Leaderboard](https://kilo.ai/leaderboard#all-models) for current availability.
See [Gateway Usage and Billing](/docs/gateway/usage-and-billing) for credit pricing details.
## Related
- [KiloClaw Overview](/docs/automate/kiloclaw/overview)
- [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms)
- [Gateway Usage and Billing](/docs/gateway/usage-and-billing)
@@ -0,0 +1,78 @@
---
title: "Troubleshooting"
description: "Common issues, diagnostics, and FAQ for KiloClaw instances"
---
# Troubleshooting
## OpenClaw Doctor
OpenClaw Doctor is the recommended first step when something isn't working. It runs diagnostics on your instance and automatically fixes common configuration issues.
To use it:
1. Make sure your instance is running
2. Click **OpenClaw Doctor** on your [dashboard](/docs/automate/kiloclaw/dashboard)
3. Watch the output as it runs — results appear in real time
## Common Questions
### Does Redeploy reset my instance?
No. Redeploy does **not** delete your files, git repos, or cron jobs. It stops the machine, applies the latest platform image and your current configuration, and starts it again with the same persistent storage. Think of it as "update and restart."
### When should I use Restart OpenClaw vs Redeploy?
- **Restart OpenClaw** — Restarts just the OpenClaw process. The machine stays up. Use this for quick recovery from a process-level issue or when you want to apply openclaw config changes.
- **Redeploy** — Stops and restarts the entire machine with the latest image and config. Use this when the changelog shows a redeploy hint, or after changing channel tokens or secrets.
### My bot isn't responding on Telegram/Discord/Slack
1. Check that the channel token is configured in [Settings](/docs/automate/kiloclaw/dashboard#channels)
2. Make sure you **Redeployed** or **Restarted OpenClaw** after saving tokens
3. Check for pending [pairing requests](/docs/automate/kiloclaw/chat-platforms#pairing-requests) — the user may need to be approved
4. Try running **OpenClaw Doctor**
### The gateway shows "Crashed"
The OpenClaw process is automatically restarted when it crashes. Check the Gateway Process tab on your dashboard for the exit code and restart count. If it keeps crashing:
1. Run **OpenClaw Doctor**
2. Try a **Redeploy** to apply the latest platform image
3. If the issue persists, join the [Kilo Discord](https://kilo.ai/discord) and share details in the KiloClaw channel
### My access code isn't working
Access codes are one-time use and expire after 10 minutes. Generate a new one by clicking **Access Code** on the dashboard. Make sure your instance is running before clicking **Open**.
### I changed the model but the agent is still using the old one
After selecting a new model, click **Save & Provision** to apply it. This refreshes the API key and saves the new model. You may also need to **Restart OpenClaw** for the change to take full effect.
## Gateway Process States
The Gateway Process tab shows the current state of the OpenClaw process inside your machine:
- **Running** — The process is up and handling requests
- **Stopped** — The process is not running
- **Starting** — The process is booting up
- **Stopping** — The process is shutting down gracefully
- **Crashed** — The process exited unexpectedly and will be automatically restarted
- **Shutting Down** — The process is stopping as part of a machine stop or redeploy
## Architecture Notes
For advanced users — how KiloClaw instances are structured:
- **Dedicated machine** — Each user gets their own machine and persistent volume. There is no shared infrastructure between users.
- **Region-pinned storage** — Your persistent volume stays in the region where your instance was originally created.
- **Network isolation** — OpenClaw binds to loopback only; external traffic is proxied through a Kilo controller.
- **Per-user authentication** — The gateway token is derived per-user for authenticating requests to your machine.
- **Encryption at rest** — Sensitive data (API keys, channel tokens) is encrypted at rest in the machine configuration.
## Related
- [KiloClaw Overview](/docs/automate/kiloclaw/overview)
- [Dashboard Reference](/docs/automate/kiloclaw/dashboard)
- [Connecting Chat Platforms](/docs/automate/kiloclaw/chat-platforms)
- [KiloClaw Pricing](/docs/automate/kiloclaw/pricing)
@@ -1,109 +1,182 @@
---
title: "Using MCP in CLI"
description: "How to use MCP servers in the CLI"
description: "How to configure and use MCP servers in the Kilo CLI"
---
# Using MCP in the CLI
The Kilo Code CLI supports MCP servers, but uses a **different configuration path** than the VS Code extension.
The Kilo CLI supports both local and remote MCP servers. Once added, MCP tools are automatically available to the LLM alongside built-in tools.
{% callout type="tip" %}
MCP servers add to your context, so be careful with which ones you enable. Certain MCP servers with many tools can quickly add up and exceed the context limit.
{% /callout %}
## Configuration Location
| Environment | MCP Settings Path |
| ----------- | --------------------------------------------------- |
| **CLI** | `~/.kilocode/cli/global/settings/mcp_settings.json` |
| **VS Code** | VS Code's global storage directory |
The CLI accepts several config filenames. The recommended file is `kilo.json`:
MCP servers configured in VS Code are **not** automatically available in the CLI. You must configure them separately.
| Scope | Recommended Path | Also supported |
| ----------- | ------------------------------------ | --------------------------- |
| **Global** | `~/.config/kilo/kilo.json` | `kilo.jsonc`, `config.json` |
| **Project** | `./kilo.json` or `./.kilo/kilo.json` | `kilo.jsonc` |
Project-level configuration takes precedence over global settings.
## Configuration Format
Edit `~/.kilocode/cli/global/settings/mcp_settings.json`:
Add MCP servers under the `mcp` key in your config file. Each server has a unique name that you can reference in prompts.
```json
{
"mcpServers": {
"server-name": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {
"API_KEY": "your_api_key"
},
"alwaysAllow": ["tool1", "tool2"],
"disabled": false
}
}
}
```
## Transport Types
### STDIO (Local Servers)
```json
{
"mcpServers": {
"local-server": {
"command": "node",
"args": ["/path/to/server.js"],
"env": {}
}
}
}
```
### Streamable HTTP (Remote Servers)
```json
{
"mcpServers": {
"remote-server": {
"type": "streamable-http",
"url": "https://your-server.com/mcp",
"headers": {
"Authorization": "Bearer token"
}
}
}
}
```
## Project-Level Configuration
You can define MCP servers per-project by creating `.kilocode/mcp.json` in your project root. Project-level servers take precedence over global settings.
## Configuration Options
| Option | Description |
| ------------- | ----------------------------------------------------------- |
| `command` | Executable to run (STDIO) |
| `args` | Command arguments (STDIO) |
| `env` | Environment variables |
| `type` | Transport type: `stdio` (default), `streamable-http`, `sse` |
| `url` | Server URL (HTTP transports) |
| `headers` | HTTP headers (HTTP transports) |
| `alwaysAllow` | Array of tool names to auto-approve |
| `disabled` | Set `true` to disable without removing |
| `timeout` | Request timeout in seconds (default: 60) |
## Auto-Approval
MCP auto-approval is controlled via CLI config (`kilocode config`):
```json
{
"autoApproval": {
"mcp": {
"mcp": {
"my-server": {
"type": "local",
"command": ["npx", "-y", "my-mcp-command"],
"enabled": true
}
}
}
```
Or via environment variable:
You can disable a server by setting `enabled` to `false` without removing it from your config.
```bash
export KILO_AUTO_APPROVAL_MCP_ENABLED=true
## Transport Types
### Local Servers
Local MCP servers run on your machine and communicate via standard input/output. Set `type` to `"local"`.
```json
{
"mcp": {
"my-local-server": {
"type": "local",
"command": ["npx", "-y", "my-mcp-command"],
"enabled": true,
"environment": {
"API_KEY": "your_api_key"
}
}
}
}
```
Per-tool auto-approval uses the `alwaysAllow` array in the server configuration.
#### Local Server Options
| Option | Type | Required | Description |
| ------------- | ------- | -------- | -------------------------------------------------------------------- |
| `type` | String | Yes | Must be `"local"`. |
| `command` | Array | Yes | Command and arguments to run the MCP server. |
| `environment` | Object | No | Environment variables to set when running the server. |
| `enabled` | Boolean | No | Enable or disable the MCP server on startup. |
| `timeout` | Number | No | Timeout in ms for fetching tools from the MCP server. Default: 5000. |
### Remote Servers
Remote MCP servers are accessed over HTTP/HTTPS. Set `type` to `"remote"`.
```json
{
"mcp": {
"my-remote-server": {
"type": "remote",
"url": "https://my-mcp-server.com/mcp",
"enabled": true,
"headers": {
"Authorization": "Bearer MY_API_KEY"
}
}
}
}
```
#### Remote Server Options
| Option | Type | Required | Description |
| --------- | ------- | -------- | -------------------------------------------------------------------- |
| `type` | String | Yes | Must be `"remote"`. |
| `url` | String | Yes | URL of the remote MCP server. |
| `enabled` | Boolean | No | Enable or disable the MCP server on startup. |
| `headers` | Object | No | HTTP headers to send with requests. |
| `timeout` | Number | No | Timeout in ms for fetching tools from the MCP server. Default: 5000. |
## Managing MCP Servers
You can manage MCP servers from the CLI:
| Command | Description |
| --------------- | ------------------------------- |
| `kilo mcp list` | List all configured MCP servers |
| `kilo mcp add` | Add an MCP server |
| `kilo mcp auth` | Authenticate with an MCP server |
Inside the interactive TUI, use the `/mcps` slash command to toggle MCP servers on or off.
## Examples
### Figma Desktop
Connect to the Figma Desktop app's MCP server:
```json
{
"mcp": {
"Figma Desktop": {
"type": "remote",
"url": "http://127.0.0.1:3845/mcp"
}
}
}
```
### Context7
Add the [Context7](https://github.com/upstash/context7) MCP server for documentation search:
```json
{
"mcp": {
"context7": {
"type": "remote",
"url": "https://mcp.context7.com/mcp"
}
}
}
```
### Everything Test Server
Add the test MCP server for development:
```json
{
"mcp": {
"mcp_everything": {
"type": "local",
"command": ["npx", "-y", "@modelcontextprotocol/server-everything"]
}
}
}
```
## Environment Variables
Use `{env:VARIABLE_NAME}` syntax in config files to reference environment variables:
```json
{
"mcp": {
"my-server": {
"type": "remote",
"url": "https://mcp.example.com/mcp",
"headers": {
"Authorization": "Bearer {env:MY_API_KEY}"
}
}
}
}
```
## Finding MCP Servers
Browse community-contributed MCP server configurations and agent skills in the [Kilo Marketplace](https://github.com/Kilo-Org/kilo-marketplace). The marketplace includes ready-to-use configs for popular tools like Figma, Sentry, and more.
@@ -18,12 +18,21 @@ Kilo for Slack brings the power of Kilo Code directly into your Slack workspace.
---
## Supported Platforms
| Platform | Integration Type | Details |
| -------- | ---------------- | --------------------------------------------------------------------|
| GitHub | GitHub App | [GitHub Setup Guide](/docs/automate/integrations#connecting-github) |
| GitLab | OAuth or PAT | [GitLab Setup Guide](/docs/automate/integrations#connecting-gitlab) |
---
## Prerequisites
Before using Kilo for Slack:
- You must have a **Kilo Code account** with available credits
- Your **GitHub Integration must be configured** via the [Integrations tab](https://app.kilo.ai/integrations) so Kilo can access your repositories
- Your **Git provider integration must be configured** via the [Integrations tab](https://app.kilo.ai/integrations) so Kilo can access your repositories
To install Kilo for Slack, simply go to the integrations menu in the sidebar on https://app.kilo.ai and set up the Slack integration.
@@ -105,9 +114,9 @@ Can you help me understand what's causing it?
## How It Works
1. **Message Kilo** — Either through DMs or by mentioning it in a channel
2. **Kilo processes your request** — Kilo uses your connected GitHub repositories to understand context
2. **Kilo processes your request** — Kilo uses your connected repositories to understand context
3. **AI generates a response** — Kilo Code's AI analyzes your request and provides helpful responses
4. **Code changes (if requested)** — For implementation requests, Kilo can create pull requests
4. **Code changes (if requested)** — For implementation requests, Kilo can create pull or merge requests
---
@@ -157,10 +166,10 @@ Kilo for Slack supports over 400+ models across different providers.
Ensure Kilo for Slack is installed in your workspace and has been added to the channel you're using.
**"Kilo can't access my repository."**
Verify your GitHub integration is configured correctly in the [Integrations tab](https://app.kilo.ai/integrations).
Verify your Git provider integration is configured correctly in the [Integrations tab](https://app.kilo.ai/integrations).
**"I'm getting incomplete responses."**
Try breaking your request into smaller, more specific questions.
**"Kilo doesn't understand my codebase."**
Make sure the repository you're asking about is connected and accessible through your GitHub integration.
Make sure the repository you're asking about is connected and accessible through your Git provider integration.
@@ -11,13 +11,6 @@ Kilo Enterprise lets your organization securely manage access using **Single Sig
**IDP-initiated logins are not currently supported.** Users must navigate to the [Kilo Web App](https://app.kilo.ai) to log in. Logging in directly from your identity provider's dashboard is not supported at this time.
{% /callout %}
## Why Enable SSO?
- **Centralized access control:** Manage permissions through your existing identity provider.
- **Faster onboarding:** New team members automatically gain access when added to your company directory.
- **Improved security:** Enforce company-wide password, MFA, and session policies.
- **Easy offboarding:** Smoothly remove access when users leave your organization.
## Prerequisites
Youll need:
@@ -25,7 +18,7 @@ Youll need:
- Admin or Owner permissions for your Kilo organization.
- Access to your **Identity Provider (IdP)** (e.g. Okta, Google Workspace, Azure AD).
## Step-by-Step Setup
## Initiating SSO Configuration
### 1. Open [Organization](https://app.kilo.ai/organizations) Dashboard
@@ -36,7 +29,30 @@ Find the Single Sign-On (SSO) Configuration panel, and click "Set up SSO":
Fill in your contact information and someone from our team will reach out soon to help you configure SSO.
## ✅ Next Steps
## Implementing SSO Configuration
Once the Kilo team has enabled SSO for your organization, your named admin will get an email from WorkOS to configure SSO.
{% callout type="warning" %}
**Save domain policy for last.**
If you configure domain policy before setting up SSO, you may lock users out of Kilo.
{% /callout %}
Your admin will need to use the WorkOS link to:
### 1. Configure your Identity Provider in WorkOS
Find the Metadata in your Identity Provider and apply that configuration in WorkOS.
### 2. Configure WorkOS in your Identity Provider
Copy the Service Provider details (Entity ID, ACS URL, and Metadata) from the WorkOS dashboard and apply them in your Identity Provider.
### 3. Configure Policy and Domain Settings in WorkOS
1. Set the organization policy and user provisioning settings according to your organization's needs.
2. Configure domain policy and domain verification in WorkOS.
After enabling SSO:
@@ -85,10 +85,10 @@ Extend Kilo Auto into four tiers.
**Model options for Auto: Small**:
| Model | Cost | Capability | Notes |
| ----- | ---- | ---------- | ----- |
| Model | Cost | Capability | Notes |
| ----------- | ---------------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------- |
| gpt-oss-20b | ~50% cheaper than GPT-5 Nano | Lower — suitable for simple background tasks like titles and summaries | Open-weight, cost-optimized option for high-volume lightweight tasks |
| GPT-5 Nano | Higher than gpt-oss-20b | Higher — better instruction following and output quality | Preferred when credits are available and task quality matters |
| GPT-5 Nano | Higher than gpt-oss-20b | Higher — better instruction following and output quality | Preferred when credits are available and task quality matters |
Auto: Small should prefer **gpt-oss-20b** when minimizing cost (e.g., free users, high-volume background tasks) and **GPT-5 Nano** when credits are available and higher output quality is desired.
@@ -1,56 +1,146 @@
---
title: "Architecture Overview"
description: "Overview of Kilo Code architecture"
description: "Overview of the Kilo platform architecture"
---
# Architecture Overview
This document provides a high-level overview of Kilo Code's architecture to help contributors understand how the different components fit together.
This document provides a high-level overview of the Kilo platform architecture to help contributors understand how the different components fit together.
## System Architecture
Kilo Code is a VS Code extension built with TypeScript that connects to various AI providers to deliver intelligent coding assistance. The architecture follows a layered approach:
Kilo is an AI coding platform built around a central CLI engine that powers every client surface — the terminal, VS Code, and the cloud. The architecture follows a layered approach where all clients communicate with the CLI over HTTP + SSE, and the CLI connects to AI providers either directly or through Kilo Cloud.
```
┌─────────────────────────────────────────────────────────────────────┐
│ VS Code Extension │
├─────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Extension Host │ │ Webview UI │ │
│ │ (src/) │◀───▶│ (webview-ui/) │ │
│ └────────┬─────────┘ └──────────────────┘ │
│ │ │
│ │ Messages │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Core Services │ │
│ ├────────────┬────────────┬────────────┬───────────────────────┤ │
│ │ Tools │ Browser │ MCP │ Code Index │ │
│ │ Service │ Session │ Servers │ Service │ │
│ └────────────┴────────────┴────────────┴───────────────────────┘ │
│ │ │
│ │ API Calls │
│ ▼ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ API Provider Layer │ │
│ ├────────────┬────────────┬────────────┬───────────────────────┤ │
│ │ Anthropic │ OpenAI │ Kilo │ OpenRouter │ │
│ │ API │ API │ Provider │ API │ │
│ └────────────┴────────────┴────────────┴───────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────┘
```mermaid
graph LR
tui["Kilo CLI (TUI)"]
vscode["VS Code Extension"]
subgraph cli ["Kilo CLI Engine"]
provider["Provider Router"]
end
subgraph cloud ["Kilo Cloud"]
gateway["Kilo Gateway"]
cloudagent["Cloud Agent"]
bot["Kilo Bot"]
claw["KiloClaw"]
review["Code Review"]
triage["Auto Triage"]
appbuilder["App Builder"]
end
providers["Inference Providers: Anthropic, OpenAI, Google, OpenRouter + 500 more"]
tui -->|SDK| cli
vscode -->|SDK| cli
cloudagent -->|Sandbox| cli
provider -- Direct --> providers
provider -- Gateway --> gateway
gateway --> providers
claw --> gateway
bot --> cloudagent
review --> cloudagent
triage --> cloudagent
appbuilder --> cloudagent
```
### Features
## Kilo CLI — The Foundation
For detailed documentation on current and planned features, see the [Architecture Features](/docs/contributing/architecture/features) page.
The CLI (`packages/opencode/`) is the core engine that all products are built on. It contains the AI agent runtime, tool execution, session management, provider integrations, and an HTTP server. Each client spawns or connects to a `kilo serve` process and communicates via HTTP + SSE using the `@kilocode/sdk`.
The CLI can run in several modes:
- **`kilo`** — Interactive TUI for terminal-based coding
- **`kilo run`** — Headless single-prompt execution
- **`kilo serve`** — HTTP server mode for client integrations
- **`kilo web`** — Browser-based UI
Key subsystems inside the CLI:
| Subsystem | Purpose |
| --------------- | ------------------------------------------------------------------------ |
| Agent Runtime | Orchestrates AI conversations, tool calls, and multi-step task execution |
| Tools Service | Built-in tools for file editing, shell execution, search, and more |
| MCP Servers | Model Context Protocol support for extending with external tools |
| LSP Client | Language Server Protocol integration for code intelligence |
| Session Manager | Persistent session state, conversation history, and checkpoints |
| Provider Router | Connects to 500+ AI models via direct APIs or Kilo Gateway |
| HTTP Server | REST API + SSE streaming for client communication |
| Config System | Project and global configuration, modes, and permissions |
## Client Layer
All clients are thin wrappers over the CLI engine.
### VS Code Extension
The VS Code extension (`packages/kilo-vscode/`) bundles the CLI binary and spawns `kilo serve` as a child process. It includes:
- **Sidebar Chat** — Primary coding assistant interface
- **Agent Manager** — Multi-session orchestration panel with git worktree isolation for running parallel tasks
### TUI
The built-in terminal UI ships with the CLI itself — a SolidJS interface rendered in the terminal via OpenTUI.
## Kilo Cloud
Kilo Cloud is the hosted platform layer that provides authentication, provider routing, and autonomous agent services. The cloud infrastructure lives in a separate repository.
### Kilo Gateway
The gateway (`packages/kilo-gateway/` in this repo, plus API routes in the cloud) handles:
- **Authentication** — Device flow auth, token management, and account linking
- **Provider Routing** — Routes AI requests through Kilo's managed API keys or the user's own keys
- **Model Catalog** — Serves the available model list and provider configuration
- **Usage & Billing** — Tracks token consumption and manages credits
### Cloud Agent
A Cloudflare Worker within Kilo Cloud that runs the Kilo CLI in isolated sandbox environments. It powers cloud-based AI coding tasks triggered via the web dashboard, webhooks, or automation workflows. It provides a secure API for:
- Creating and managing coding sessions with full GitHub/GitLab integration
- Running AI tasks in Docker containers with the CLI pre-installed
- Streaming results back via WebSocket
### Kilo Bot
The GitHub/GitLab bot that responds to issue comments and PR mentions. It dispatches work to the Cloud Agent, enabling users to trigger AI coding tasks directly from their repositories.
### KiloClaw
A multi-tenant compute platform running on Fly.io, orchestrated by a Cloudflare Worker. Each user gets a dedicated persistent machine running an OpenClaw gateway, coordinated via Durable Objects for state management and self-healing reconciliation.
### Code Review
An automated code review service that subscribes to GitHub webhooks, dispatches reviews through the Cloud Agent, and posts feedback directly on pull requests. Supports per-organization concurrency limits and automatic queuing.
### Auto Triage
An automated issue triage service that classifies GitHub issues (bug, feature, question), detects duplicates via vector similarity search, and optionally creates fix PRs for high-confidence actionable issues.
### App Builder
A service that builds and deploys user applications via the Cloud Agent. Users can generate full applications from prompts, with the App Builder orchestrating the Cloud Agent to scaffold, iterate, and deploy the result.
### Supporting Services
| Service | Purpose |
| -------------------- | ------------------------------------------------------------------------------------ |
| Webhook Agent Ingest | Named webhook endpoints that capture HTTP requests and queue delivery to Cloud Agent |
| AI Attribution | Tracks line-level AI-generated code attribution when users accept or reject edits |
| Session Ingest | Ingests and stores CLI session data for analytics |
| Observability | Telemetry pipelines for monitoring cloud services |
## Key Concepts
### Modes
Modes are configurable presets that customize Kilo Code's behavior:
Modes are configurable presets that customize the agent's behavior:
- Define which tools are available
- Set custom system prompts
@@ -59,7 +149,7 @@ Modes are configurable presets that customize Kilo Code's behavior:
### Model Context Protocol (MCP)
MCP enables extending Kilo Code with external tools:
MCP enables extending the agent with external tools:
- Servers provide additional capabilities
- Standardized protocol for tool communication
@@ -73,75 +163,79 @@ Git-based state management for safe exploration:
- Enables rolling back to previous states
- Shadow repository for isolation
### Code Indexing
### Worktrees
Semantic search over the codebase:
Git worktree isolation for parallel task execution:
- Embeddings-based search
- Vector database storage (LanceDB/Qdrant)
- Automatic chunking and indexing
- Each agent session can operate in its own worktree
- Prevents conflicts between concurrent tasks
- Used by the Agent Manager in VS Code for multi-session workflows
## Development Patterns
### Message Passing
### Client-Server Communication
The extension uses VS Code's webview message API:
All clients communicate with the CLI via its HTTP + SSE API. The `@kilocode/sdk` package provides a TypeScript client:
```typescript
// Extension → Webview
panel.webview.postMessage({ type: "response", data: ... });
import { KiloClient } from "@kilocode/sdk"
// Webview → Extension
vscode.postMessage({ type: "request", data: ... });
const client = new KiloClient({ baseUrl: "http://localhost:3000" })
const session = await client.session.create({ ... })
```
### Service Architecture
### Namespace Module Pattern
Services are typically singletons with clear interfaces:
The CLI uses a namespace module pattern for organizing related functionality:
```typescript
class CodeIndexService {
private static instance: CodeIndexService
export namespace Session {
export const create = fn(CreateSchema, async (input) => {
// ...
})
static getInstance(): CodeIndexService {
if (!this.instance) {
this.instance = new CodeIndexService()
}
return this.instance
}
export const list = fn(ListSchema, async (input) => {
// ...
})
}
```
### Tool Implementation
Tools follow a consistent pattern:
Tools follow a consistent pattern with Zod schema validation:
```typescript
interface Tool {
name: string
description: string
parameters: z.ZodSchema
execute(params: unknown): Promise<ToolResult>
}
export const ReadTool = Tool.define({
name: "read",
description: "Read a file",
parameters: z.object({
path: z.string(),
}),
async execute(params) {
// ...
},
})
```
## Build System
The project uses:
- **pnpm** - Package management (monorepo workspaces)
- **esbuild** - Fast bundling for extension
- **Vite** - Webview UI development
- **TypeScript** - Type checking across all packages
- **Vitest** - Test runner
- **Bun** Package management (monorepo workspaces) and runtime
- **Turborepo** — Monorepo task orchestration
- **esbuild** — Bundling for the CLI and VS Code extension
- **TypeScript** Type checking via `tsgo` across all packages
- **Vitest / Bun test** Test runner
## Testing
## Repositories
- **Unit tests** - `*.spec.ts` files alongside source
- **Integration tests** - E2E tests in `e2e/` directory
- **Run tests**: `cd src && pnpm test` or `cd webview-ui && pnpm test`
| Repository | Contents |
| --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode) | CLI engine, VS Code extension, SDK, gateway client, telemetry, docs, UI components |
| Cloud (private) | Web dashboard, Cloud Agent, Kilo Bot, KiloClaw, code review, auto triage, billing, and supporting Cloudflare Workers |
## Further Reading
- [Development Environment](/docs/contributing/development-environment) - Setup guide
- [Tools Reference](/docs/automate/tools) - Available tools
- [Development Environment](/docs/contributing/development-environment) Setup guide
- [Architecture Features](/docs/contributing/architecture/features) — Detailed feature specs
- [Ecosystem](/docs/contributing/ecosystem) — Related projects and integrations
@@ -18,7 +18,7 @@ If you'd like to migrate your memory bank content to AGENTS.md:
1. Examine the contents in `.kilocode/rules/memory-bank/`
2. Move that content into your project's `AGENTS.md` file (or ask Kilo to do it for you)
{% /callout %}
{% /callout %}
## What is AGENTS.md?
@@ -17,35 +17,9 @@ Get started with Kilo Code by installing it on your preferred platform. Choose y
{% partial file="install-vscode.md" /%}
{% /tab %}
{% tab label="JetBrains" %}
{% tab label="VS Code (Preview)" %}
## JetBrains IDEs
{% partial file="install-jetbrains.md" /%}
{% /tab %}
{% tab label="CLI" %}
## Command Line Interface
{% partial file="install-cli.md" /%}
{% /tab %}
{% tab label="Slack" %}
## Slack Integration
{% partial file="install-slack.md" /%}
{% /tab %}
{% tab label="Other IDEs" %}
{% partial file="install-other-ides.md" /%}
{% /tab %}
{% /tabs %}
## Pre-Release Extension
## VS Code Preview Extension
{% callout type="info" %}
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.
@@ -82,6 +56,35 @@ If you need to return to the stable version:
Report issues or provide feedback in the [Kilo-Org/kilocode repository](https://github.com/Kilo-Org/kilocode/issues).
{% /tab %}
{% tab label="JetBrains" %}
## JetBrains IDEs
{% partial file="install-jetbrains.md" /%}
{% /tab %}
{% tab label="CLI" %}
## Command Line Interface
{% partial file="install-cli.md" /%}
{% /tab %}
{% tab label="Slack" %}
## Slack Integration
{% partial file="install-slack.md" /%}
{% /tab %}
{% tab label="Other IDEs" %}
{% partial file="install-other-ides.md" /%}
{% /tab %}
{% /tabs %}
## Manual Installations
### Open VSX Registry
@@ -1,4 +1,10 @@
module.exports = [
{
source: "/docs/automate/kiloclaw",
destination: "/docs/automate/kiloclaw/overview",
basePath: false,
permanent: true,
},
{
source: "/docs/features/custom-modes",
destination: "/docs/customize/custom-modes",
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 32 32">
<rect width="32" height="32" fill="#f0e68c"/>
<g fill="#000000">
<path d="M23,26v-2h3v-5l-2-2h-4v2h-3v5l2,2h4ZM20,20h3v3h-3v-3Z"/>
<rect x="12" y="17" width="3" height="3"/>
<polygon points="26 12 23 12 23 9 20 6 17 6 17 9 20 9 20 12 17 12 17 15 26 15 26 12"/>
<path d="M0,0v32h32V0H0ZM29,29H3V3h26v26Z"/>
<polygon points="15 26 15 23 9 23 9 17 6 17 6 23.1875 8.8125 26 15 26"/>
<rect x="12" y="6" width="3" height="3"/>
<polygon points="9 12 12 12 12 15 15 15 15 12 12 9 9 9 9 6 6 6 6 15 9 15 9 12"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 674 B

+7
View File
@@ -36,6 +36,13 @@
box-sizing: border-box;
}
.scrollbar-none {
scrollbar-width: none; /* Firefox */
}
.scrollbar-none::-webkit-scrollbar {
display: none; /* Chrome, Safari, Edge */
}
html,
body {
overflow-x: hidden;
Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

@@ -0,0 +1,19 @@
{
"name": "Kilo Code",
"short_name": "Kilo",
"icons": [
{
"src": "/docs/favicon/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/docs/favicon/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"theme_color": "#617A91",
"background_color": "#ffffff",
"display": "standalone"
}
+2 -2
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@kilocode/kilo-gateway",
"version": "7.0.30",
"version": "7.0.33",
"type": "module",
"license": "MIT",
"description": "Unified Kilo Gateway package for OpenCode - authentication, provider, and API integration",
@@ -29,7 +29,7 @@
"dependencies": {
"@kilocode/plugin": "workspace:*",
"@kilocode/sdk": "workspace:*",
"@openrouter/ai-sdk-provider": "1.5.2",
"@openrouter/ai-sdk-provider": "1.5.4",
"@clack/prompts": "1.0.0-alpha.1",
"ai": "catalog:",
"open": "10.1.2",
+2 -2
View File
@@ -19,10 +19,10 @@ export const KILO_OPENROUTER_BASE = `${KILO_API_BASE}/api/openrouter`
export const POLL_INTERVAL_MS = 3000
/** Default model for authenticated users */
export const DEFAULT_MODEL = "anthropic/claude-sonnet-4"
export const DEFAULT_MODEL = "kilo/auto"
/** Default model for anonymous/free usage */
export const DEFAULT_FREE_MODEL = "minimax/minimax-m2.1:free"
export const DEFAULT_FREE_MODEL = "kilo/auto-free"
/** Token expiration duration in milliseconds (1 year) */
export const TOKEN_EXPIRATION_MS = 365 * 24 * 60 * 60 * 1000
@@ -30,7 +30,7 @@ const NOTIFICATIONS_TIMEOUT_MS = 5000
* Fetch notifications from Kilo API
*
* @param options - Configuration with token and optional organization ID
* @returns Array of notifications filtered for CLI display
* @returns Array of notifications from the Kilo API (clients filter by showIn)
*/
export async function fetchKilocodeNotifications(options: {
kilocodeToken?: string
@@ -57,11 +57,7 @@ export async function fetchKilocodeNotifications(options: {
if (!result.success) return []
// Filter to show notifications meant for CLI (or no specific target)
// Accept "cli", "extension", or no showIn field (matches old Kilo CLI behavior)
return result.data.notifications.filter(
({ showIn }) => !showIn || showIn.includes("cli") || showIn.includes("extension"),
)
return result.data.notifications
} catch {
return []
}
+36 -14
View File
@@ -1,4 +1,3 @@
// kilocode_change - Kilo Gateway server routes
/**
* Kilo Gateway specific routes
* Handles profile fetching and organization management for Kilo Gateway provider
@@ -8,10 +7,10 @@
import { fetchProfile, fetchBalance } from "../api/profile.js"
import { fetchKilocodeNotifications, KilocodeNotificationSchema } from "../api/notifications.js"
import { KILO_API_BASE, HEADER_FEATURE } from "../api/constants.js" // kilocode_change - added HEADER_FEATURE
import { buildKiloHeaders } from "../headers.js" // kilocode_change
import type { ImportDeps, DrizzleDb } from "../cloud-sessions.js" // kilocode_change
import { fetchCloudSession, fetchCloudSessionForImport, importSessionToDb } from "../cloud-sessions.js" // kilocode_change
import { KILO_API_BASE, HEADER_FEATURE } from "../api/constants.js"
import { buildKiloHeaders } from "../headers.js"
import type { ImportDeps, DrizzleDb } from "../cloud-sessions.js"
import { fetchCloudSession, fetchCloudSessionForImport, importSessionToDb } from "../cloud-sessions.js"
// Type definitions for OpenCode dependencies (injected at runtime)
type Hono = any
@@ -97,6 +96,27 @@ export function createKiloRoutes(deps: KiloRoutesDeps) {
currentOrgId: z.string().nullable(),
})
const FimStreamChunk = z.object({
choices: z
.array(
z.object({
delta: z
.object({
content: z.string().optional(),
})
.optional(),
}),
)
.optional(),
usage: z
.object({
prompt_tokens: z.number().optional(),
completion_tokens: z.number().optional(),
})
.optional(),
cost: z.number().optional(),
})
return new Hono()
.get(
"/profile",
@@ -194,7 +214,7 @@ export function createKiloRoutes(deps: KiloRoutesDeps) {
description: "Streaming FIM completion response",
content: {
"text/event-stream": {
schema: resolver(z.any()),
schema: resolver(FimStreamChunk),
},
},
},
@@ -223,6 +243,8 @@ export function createKiloRoutes(deps: KiloRoutesDeps) {
return c.json({ error: "No valid token found" }, 401)
}
const organizationId = auth.type === "oauth" ? auth.accountId : undefined
const { prefix, suffix, model, maxTokens, temperature } = c.req.valid("json")
const fimModel = model ?? "mistralai/codestral-2501"
const fimMaxTokens = maxTokens ?? 256
@@ -231,16 +253,16 @@ export function createKiloRoutes(deps: KiloRoutesDeps) {
const baseApiUrl = KILO_API_BASE + "/api/"
const endpoint = new URL("fim/completions", baseApiUrl)
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...buildKiloHeaders(undefined, { kilocodeOrganizationId: organizationId }),
[HEADER_FEATURE]: "autocomplete",
}
const response = await fetch(endpoint, {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
// kilocode_change start - include kilo headers with autocomplete feature override
...buildKiloHeaders(),
[HEADER_FEATURE]: "autocomplete",
// kilocode_change end
},
headers,
body: JSON.stringify({
model: fimModel,
prompt: prefix,
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@kilocode/kilo-i18n",
"version": "7.0.30",
"version": "7.0.33",
"type": "module",
"license": "MIT",
"description": "Kilo-specific i18n translations and overrides",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@kilocode/kilo-telemetry",
"version": "7.0.30",
"version": "7.0.33",
"type": "module",
"license": "MIT",
"description": "Telemetry for Kilo CLI - PostHog analytics integration",
View File
+3
View File
@@ -0,0 +1,3 @@
storybook-static/
test-results/
playwright-report/
+5 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@kilocode/kilo-ui",
"version": "7.0.30",
"version": "7.0.33",
"type": "module",
"license": "MIT",
"exports": {
@@ -84,6 +84,7 @@
"solid-js": "catalog:"
},
"devDependencies": {
"@playwright/test": "1.58.2",
"@storybook/addon-a11y": "10.2.10",
"@storybook/addon-docs": "10.2.10",
"@storybook/addon-themes": "10.2.10",
@@ -97,7 +98,9 @@
},
"scripts": {
"storybook": "storybook dev -p 6006",
"build-storybook": "storybook build"
"build-storybook": "storybook build",
"test:visual": "playwright test",
"test:visual:update": "playwright test --update-snapshots"
},
"dependencies": {
"@kobalte/core": "0.13.11"
+41
View File
@@ -0,0 +1,41 @@
import { defineConfig, devices } from "@playwright/test"
export default defineConfig({
testDir: "./tests",
testMatch: "**/*.spec.ts",
fullyParallel: true,
forbidOnly: !!process.env["CI"],
retries: process.env["CI"] ? 1 : 0,
// Number of parallel workers — defaults to half the CPU count locally,
// override with PLAYWRIGHT_WORKERS env var or --workers CLI flag
workers: process.env["PLAYWRIGHT_WORKERS"]
? Number.parseInt(process.env["PLAYWRIGHT_WORKERS"]!, 10) || undefined
: undefined,
reporter: [["html", { open: "never" }], ["list"]],
use: {
baseURL: "http://localhost:6006",
viewport: { width: 1280, height: 720 },
reducedMotion: "reduce",
screenshot: "only-on-failure",
},
projects: [
{
name: "chromium",
use: { ...devices["Desktop Chrome"] },
},
],
webServer: {
command:
"bunx storybook build -o ./storybook-static && bunx http-server ./storybook-static -p 6006 --silent",
url: "http://localhost:6006",
reuseExistingServer: !process.env["CI"],
timeout: 300_000,
},
timeout: 60_000,
expect: {
timeout: 10_000,
toHaveScreenshot: {
maxDiffPixelRatio: 0.01,
},
},
})
@@ -6,4 +6,78 @@
min-width: 0;
overflow: hidden;
}
[data-slot="basic-tool-tool-info"] {
font-size: 12px;
}
[data-slot="message-part-title"] {
align-items: baseline;
}
[data-slot="message-part-title-area"] {
align-items: baseline;
}
[data-slot="basic-tool-tool-info-main"] {
align-items: baseline;
}
[data-slot="basic-tool-icon"] {
display: none;
}
[data-slot="basic-tool-tool-subtitle"] {
font-size: 12px;
}
[data-slot="basic-tool-tool-title"] {
font-size: 14px;
}
[data-slot="message-part-title-text"] {
font-size: 14px;
}
[data-slot="message-part-title-filename"] {
font-size: 12px;
}
}
/* Tool icon in trigger: visible in VS Code theme */
html[data-theme="kilo-vscode"] [data-component="tool-trigger"] {
[data-slot="basic-tool-icon"] {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
color: var(--icon-base);
[data-component="icon"] {
display: flex;
}
}
}
/* Card styling for tool calls in the VS Code sidebar theme */
html[data-theme="kilo-vscode"] [data-component="tool-part-wrapper"] {
border-radius: var(--radius-md);
border: 1px solid var(--border-weak-base, var(--vscode-panel-border));
overflow: hidden;
/* Header trigger — add bottom border when the collapsible is open */
[data-component="collapsible"].tool-collapsible {
gap: 0px;
border-radius: 0;
[data-slot="collapsible-trigger"] {
padding: 0 8px;
height: 36px;
background-color: var(--surface-inset-base, var(--vscode-sideBar-background));
}
[data-slot="collapsible-trigger"][aria-expanded="true"] {
border-bottom: 1px solid var(--border-weak-base, var(--vscode-panel-border));
}
}
}
@@ -0,0 +1,9 @@
[data-component="diff-changes"] {
[data-slot="diff-changes-additions"] {
font-size: 12px;
}
[data-slot="diff-changes-deletions"] {
font-size: 12px;
}
}
+7 -2
View File
@@ -10,11 +10,11 @@
h4,
h5,
h6 {
margin-top: 1rem;
margin-top: 0;
}
hr {
margin: 1rem 0;
margin: 0;
}
pre {
@@ -44,4 +44,9 @@
}
}
}
[data-component="markdown-code"] {
background: var(--background-stronger);
margin-bottom: 1rem;
}
}
@@ -2,6 +2,8 @@
/* Kilo Message Part overrides */
[data-component="text-part"] {
margin-top: 8px;
[data-slot="text-part-body"] {
margin-top: 0;
}
@@ -29,6 +31,47 @@
}
}
/* Task tool child-session tool list (v1.0.25 style) */
[data-component="task-tools"] {
padding: 8px 12px;
display: flex;
flex-direction: column;
gap: 6px;
[data-slot="task-tool-item"] {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-weak);
[data-slot="icon-svg"] {
flex-shrink: 0;
color: var(--icon-weak);
}
}
[data-slot="task-tool-title"] {
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-weight: var(--font-weight-medium);
line-height: var(--line-height-large);
color: var(--text-weak);
flex-shrink: 0;
}
[data-slot="task-tool-subtitle"] {
font-family: var(--font-family-sans);
font-size: var(--font-size-small);
font-weight: var(--font-weight-regular);
line-height: var(--line-height-large);
color: var(--text-weaker);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
}
html[data-theme="kilo-vscode"] [data-component="bash-output"] {
background: var(--vscode-terminal-background, var(--vscode-panel-background));
@@ -36,21 +79,38 @@ html[data-theme="kilo-vscode"] [data-component="bash-output"] {
color: var(--vscode-terminal-foreground, var(--vscode-editor-foreground));
}
[data-slot="bash-scroll"] {
scrollbar-width: thin;
scrollbar-color: var(--vscode-scrollbarSlider-background) transparent;
&::-webkit-scrollbar-thumb {
background: var(--vscode-scrollbarSlider-background);
border-radius: 4px;
}
&::-webkit-scrollbar-thumb:hover {
background: var(--vscode-scrollbarSlider-hoverBackground);
}
}
[data-slot="bash-copy"] [data-component="icon-button"][data-variant="secondary"] {
background: var(--vscode-terminal-background, var(--vscode-panel-background));
}
}
[data-component="tool-output"] {
margin-bottom: 0px;
}
/* Remove the empty space below user message bubbles.
* The upstream copy wrapper is a normal-flow block with min-height + margin,
* so it reserves ~28px even when invisible. Override it to be absolutely
* positioned over the bottom-right corner of the bubble zero layout impact
* when hidden, overlays on hover exactly like the text-part copy button. */
[data-component="user-message"] {
position: relative;
[data-slot="user-message-copy-wrapper"] {
position: absolute;
top: 4px;
right: 4px;
bottom: auto;
min-height: unset;
margin-top: 0;
width: auto;
/* hide meta text; only the icon-button matters in the sidebar */
[data-slot="user-message-meta-wrap"] {
display: none;
}
}
}
[data-component="question-answers"] {
padding: 8px;
}
+66
View File
@@ -54,6 +54,72 @@
height: 0;
}
/*
* Scrollbar utility class + universal scrollable-element styling.
*
* `.kilo-scrollbar` explicit opt-in class for any scrollable element.
* `[data-scrollable]` data attribute used by kilo-ui components internally.
*
* Both selectors receive identical thin, token-aware scrollbar styling.
* In the VS Code theme the colors resolve to native VS Code scrollbar tokens.
*
* Usage (class): <div class="kilo-scrollbar" style="overflow-y: auto">
* Usage (attribute): <div data-scrollable style="overflow-y: auto">
*/
:is(.kilo-scrollbar, [data-scrollable]) {
/* Firefox */
scrollbar-width: thin;
scrollbar-color: rgba(121, 121, 121, 0.4) transparent;
/* WebKit */
&::-webkit-scrollbar {
width: 8px;
height: 8px;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: rgba(121, 121, 121, 0.4);
border-radius: 4px;
border: 2px solid transparent;
background-clip: padding-box;
}
&::-webkit-scrollbar-thumb:hover {
background: rgba(100, 100, 100, 0.7);
}
&::-webkit-scrollbar-corner {
background: transparent;
}
&::-webkit-scrollbar-button {
display: none;
width: 0;
height: 0;
}
}
/* VS Code theme: use native VS Code scrollbar color tokens */
html[data-theme="kilo-vscode"] :is(.kilo-scrollbar, [data-scrollable]) {
scrollbar-color: var(--vscode-scrollbarSlider-background) transparent;
&::-webkit-scrollbar-thumb {
background: var(--vscode-scrollbarSlider-background);
}
&::-webkit-scrollbar-thumb:hover {
background: var(--vscode-scrollbarSlider-hoverBackground);
}
&::-webkit-scrollbar-thumb:active {
background: var(--vscode-scrollbarSlider-activeBackground);
}
}
/* ===== VS Code extension: inherit native styling ===== */
html[data-theme="kilo-vscode"] {
+1
View File
@@ -16,6 +16,7 @@
@import "../components/code.css";
@import "../components/context-menu.css";
@import "../components/dialog.css";
@import "../components/diff-changes.css";
@import "../components/dropdown-menu.css";
@import "../components/icon-button.css";
@import "../components/inline-input.css";
@@ -0,0 +1,74 @@
import { test, expect, type Page } from "@playwright/test"
type Story = {
id: string
title: string
name: string
}
type StoriesIndex = {
stories?: Record<string, Story>
entries?: Record<string, Story>
}
const STORYBOOK_URL = "http://localhost:6006"
// Fetched once per worker process — cheap HTTP call to the already-running Storybook
async function fetchStories(): Promise<Story[]> {
const res = await fetch(`${STORYBOOK_URL}/index.json`).catch(() =>
fetch(`${STORYBOOK_URL}/stories.json`),
)
if (!res.ok) throw new Error(`Storybook index fetch failed: ${res.status} ${res.statusText}`)
const data = (await res.json()) as StoriesIndex
const map = data.entries ?? data.stories ?? {}
return Object.values(map).filter((s) => s.id && !s.id.endsWith("--docs"))
}
async function disableAnimations(page: Page) {
await page.addStyleTag({
content: `
*, *::before, *::after {
animation-duration: 0s !important;
animation-delay: 0s !important;
transition-duration: 0s !important;
transition-delay: 0s !important;
}
`,
})
}
// Stories to skip from visual regression:
// - Font/Favicon: inject into <head>, no visible content in #storybook-root
// - Typewriter: uses JS setTimeout + Math.random(), inherently non-deterministic
const SKIP = new Set([
"components-font--default",
"components-font--nerd-fonts",
"components-favicon--default",
"components-typewriter--default",
"components-typewriter--short",
"components-typewriter--long",
"components-typewriter--as-heading",
"components-typewriter--with-class",
])
// Generate one test() per story so Playwright's scheduler can distribute
// them freely across workers — no manual sharding needed.
const stories = (await fetchStories()).filter((s) => !SKIP.has(s.id))
for (const story of stories) {
test(`${story.title} / ${story.name}`, async ({ page }) => {
await page.goto(
`/iframe.html?id=${story.id}&viewMode=story&globals=colorScheme:dark;theme:kilo`,
{ waitUntil: "load" },
)
await disableAnimations(page)
// Wait for Kobalte/SolidJS to finish hydrating interactive components
await page.waitForSelector("#storybook-root *", { state: "attached" })
// Screenshot just the story content, not the full 1280x720 canvas.
// Use [component, variant] path so snapshots are grouped per component dir.
const [component, variant] = story.id.split("--")
const root = page.locator("#storybook-root")
await expect(root).toHaveScreenshot([component, `${variant}.png`])
})
}
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:5a9cc941f1b53c84801131c244c5ed221e8cac90196b66a39f612af303d94c94
size 8976
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d4f711edf59c220e6a51b6504bb2e8ecd8a7985788e043dd5909e2a242f034de
size 6948
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:e087e90137add1cf6b3b1a31e7110d00526a8dd5a7d0a79e9d7cecd334eaff01
size 20440
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:f0386bc84951dc3e805b760c490cc26b68034f5fbe1c26719ce41225b2a9e4ca
size 1125
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a947b9aa3971baa684293e773785c2242bc5c6e29f1a55fe82a90af996fe0d20
size 1311
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:847d6427507680baf18dbf5bea94dafc8caa25fd81c2ea7528d40fd249d1e700
size 743
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c083a3befc996442140690aa1205c9757e3a42a5319d9a2dde4c9752a6213e75
size 1321
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:61cb8e2353522bbcaa9a4620d99b38352a1541c3c5446a1a494aa98162bc5859
size 373
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:719b8329543d629a9243cbe929f2c2fc30b77d7a540c08678220f7653badb1c8
size 366
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dc3aa85936933993e0edbe56fe3e1b6337556bf913aa35edfd37caab62edfa74
size 598
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6eec16318fdc68f8226db0230f38fb0b3282fb174e11495b8c50b2c09cb7ab1f
size 383
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:befa25f36efd49672cad2eb6eb7ef0802269981ec4b7eafac343b55288c58fa1
size 579
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:79b80c13a1fa198f1602c85728a48467ac9b47c6430dadd6ff698f9c4d39980e
size 809
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dfd2a0c4eb4e848a61d1cc309b637980d71e09325fb330f4329df05e754464d0
size 9497
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:7ff2fc5b2f48973c4f217292fca770cb8fafafaf084d512d81486243656345b3
size 2469
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6213f881a8eaa9a6fde7e4f46fbced82a308afe426433330426469975e9d670e
size 4292
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:1a9813f847aa72accf4f17d4b3359717274c34189606a0a8cfee203a8e32101c
size 1622
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:afb54400b855748eac7722a9cef3877fa0b70fd56f466d396a93559d7634767c
size 3637
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:143ce0f9a640b0558d381485972f5818feacd84d2a626187dfe644f86d46244e
size 1772
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:53f1ef3da39ca34fe50fe48f36a607c83e5b751a471812e1e3eb41d8aaeac5d1
size 3433
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:d0f6231acb66fe78d5092a7225fd5614f27f4c77c61230bf7151db0e80d196b9
size 6895
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ce98be74244727ae4175aeb8d130be0b3f00fedb8dfa1443a45f9ceb909e1418
size 1299
@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:56baa5ea0a41832ec201ed4ab51ac3889c5d55824c1629ab9bdbc9c3c9ae5637
size 1310

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