Merge pull request #439 from Kilo-Org/feat/import-kilocode-docs

feat: import kilocode-docs with full history
This commit is contained in:
Jean du Plessis
2026-02-19 12:04:22 +02:00
committed by GitHub
364 changed files with 28961 additions and 37 deletions
+30
View File
@@ -0,0 +1,30 @@
name: docs-build
on:
push:
branches: [dev]
paths:
- "packages/kilo-docs/**"
pull_request:
paths:
- "packages/kilo-docs/**"
workflow_dispatch:
jobs:
build:
name: Build docs site
runs-on: blacksmith-4vcpu-ubuntu-2404
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Build site
run: bun run --filter @kilocode/kilo-docs build
env:
NEXT_PUBLIC_POSTHOG_KEY: ${{ secrets.POSTHOG_API_KEY }}
- name: Run tests
run: bun run --filter @kilocode/kilo-docs test
+384 -37
View File
@@ -106,6 +106,34 @@
"vite": "catalog:",
},
},
"packages/kilo-docs": {
"name": "@kilocode/kilo-docs",
"version": "1.0.0",
"dependencies": {
"@docsearch/css": "^4",
"@docsearch/js": "^4",
"@markdoc/markdoc": "^0.5.4",
"@markdoc/next.js": "^0.5.0",
"@vscode/codicons": "^0.0.44",
"js-yaml": "^4.1.0",
"next": "^16.1.5",
"posthog-js": "^1.335.3",
"prismjs": "^1.30.0",
"react": "^19.2.4",
"react-dom": "^19.2.4",
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.18",
"@types/node": "^25.0.10",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"autoprefixer": "^10.4.23",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3",
"vitest": "^3.2.3",
},
},
"packages/kilo-gateway": {
"name": "@kilocode/kilo-gateway",
"version": "1.0.23",
@@ -429,6 +457,7 @@
},
},
"trustedDependencies": [
"protobufjs",
"esbuild",
"web-tree-sitter",
"tree-sitter-bash",
@@ -544,6 +573,8 @@
"@ai-sdk/xai": ["@ai-sdk/xai@2.0.56", "", { "dependencies": { "@ai-sdk/openai-compatible": "1.0.32", "@ai-sdk/provider": "2.0.1", "@ai-sdk/provider-utils": "3.0.20" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-FGlqwWc3tAYqDHE8r8hQGQLcMiPUwgz90oU2QygUH930OWtCLapFkSu114DgVaIN/qoM1DUX+inv0Ee74Fgp5g=="],
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.39.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg=="],
@@ -728,6 +759,12 @@
"@dimforge/rapier2d-simd-compat": ["@dimforge/rapier2d-simd-compat@0.17.3", "", {}, "sha512-bijvwWz6NHsNj5e5i1vtd3dU2pDhthSaTUZSh14DUGGKJfw8eMnlWZsxwHBxB/a3AXVNDjL9abuHw1k9FGR+jg=="],
"@docsearch/css": ["@docsearch/css@4.6.0", "", {}, "sha512-YlcAimkXclvqta47g47efzCM5CFxDwv2ClkDfEs/fC/Ak0OxPH2b3czwa4o8O1TRBf+ujFF2RiUwszz2fPVNJQ=="],
"@docsearch/js": ["@docsearch/js@4.6.0", "", {}, "sha512-9/rbgkm/BgTq46cwxIohvSAz3koOFjnPpg0mwkJItAfzKbQIj+310PvwtgUY1YITDuGCag6yOL50GW2DBkaaBw=="],
"@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
"@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.2", "", { "os": "aix", "cpu": "ppc64" }, "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw=="],
"@esbuild/android-arm": ["@esbuild/android-arm@0.27.2", "", { "os": "android", "cpu": "arm" }, "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA=="],
@@ -850,6 +887,56 @@
"@humanwhocodes/retry": ["@humanwhocodes/retry@0.4.3", "", {}, "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ=="],
"@img/colour": ["@img/colour@1.0.0", "", {}, "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw=="],
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
"@internationalized/date": ["@internationalized/date@3.11.0", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-BOx5huLAWhicM9/ZFs84CzP+V3gBW6vlpM02yzsdYC7TGlZJX1OJiEEHcSayF00Z+3jLlm4w79amvSt6RqKN3Q=="],
"@internationalized/number": ["@internationalized/number@3.6.5", "", { "dependencies": { "@swc/helpers": "^0.5.0" } }, "sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g=="],
@@ -938,6 +1025,8 @@
"@kilocode/cli": ["@kilocode/cli@workspace:packages/opencode"],
"@kilocode/kilo-docs": ["@kilocode/kilo-docs@workspace:packages/kilo-docs"],
"@kilocode/kilo-gateway": ["@kilocode/kilo-gateway@workspace:packages/kilo-gateway"],
"@kilocode/kilo-i18n": ["@kilocode/kilo-i18n@workspace:packages/kilo-i18n"],
@@ -962,12 +1051,34 @@
"@lukeed/ms": ["@lukeed/ms@2.0.2", "", {}, "sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA=="],
"@markdoc/markdoc": ["@markdoc/markdoc@0.5.4", "", { "optionalDependencies": { "@types/linkify-it": "^3.0.1", "@types/markdown-it": "12.2.3" }, "peerDependencies": { "@types/react": "*", "react": "*" }, "optionalPeers": ["@types/react", "react"] }, "sha512-36YFNlqFk//gVNGm5xZaTWVwbAVF2AOmVjf1tiUrS6tCoD/YSkVy2E3CkAfhc5MlKcjparL/QFHCopxL4zRyaQ=="],
"@markdoc/next.js": ["@markdoc/next.js@0.5.0", "", { "dependencies": { "js-yaml": "^4.1.0" }, "peerDependencies": { "@markdoc/markdoc": "*", "next": "*", "react": "*" } }, "sha512-gzWvRc2dlxArQn1mDS4SHed46vkAoKBbXkELihQRYv1eVSA0u9eoNEdJXNuBL4Ajn9j2dPpwZp6nAVjN4nzZlA=="],
"@mdx-js/react": ["@mdx-js/react@3.1.1", "", { "dependencies": { "@types/mdx": "^2.0.0" }, "peerDependencies": { "@types/react": ">=16", "react": ">=16" } }, "sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw=="],
"@mixmark-io/domino": ["@mixmark-io/domino@2.2.0", "", {}, "sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw=="],
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.25.2", "", { "dependencies": { "@hono/node-server": "^1.19.7", "ajv": "^8.17.1", "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "jose": "^6.1.1", "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.25 || ^4.0", "zod-to-json-schema": "^3.25.0" }, "peerDependencies": { "@cfworker/json-schema": "^4.1.1" }, "optionalPeers": ["@cfworker/json-schema"] }, "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww=="],
"@next/env": ["@next/env@16.1.6", "", {}, "sha512-N1ySLuZjnAtN3kFnwhAwPvZah8RJxKasD7x1f8shFqhncnWZn4JMfg37diLNuoHsLAlrDfM3g4mawVdtAG8XLQ=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@16.1.6", "", { "os": "darwin", "cpu": "arm64" }, "sha512-wTzYulosJr/6nFnqGW7FrG3jfUUlEf8UjGA0/pyypJl42ExdVgC6xJgcXQ+V8QFn6niSG2Pb8+MIG1mZr2vczw=="],
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@16.1.6", "", { "os": "darwin", "cpu": "x64" }, "sha512-BLFPYPDO+MNJsiDWbeVzqvYd4NyuRrEYVB5k2N3JfWncuHAy2IVwMAOlVQDFjj+krkWzhY2apvmekMkfQR0CUQ=="],
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-OJYkCd5pj/QloBvoEcJ2XiMnlJkRv9idWA/j0ugSuA34gMT6f5b7vOiCQHVRpvStoZUknhl6/UxOXL4OwtdaBw=="],
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@16.1.6", "", { "os": "linux", "cpu": "arm64" }, "sha512-S4J2v+8tT3NIO9u2q+S0G5KdvNDjXfAv06OhfOzNDaBn5rw84DGXWndOEB7d5/x852A20sW1M56vhC/tRVbccQ=="],
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-2eEBDkFlMMNQnkTyPBhQOAyn2qMxyG2eE7GPH2WIDGEpEILcBPI/jdSv4t6xupSP+ot/jkfrCShLAa7+ZUPcJQ=="],
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@16.1.6", "", { "os": "linux", "cpu": "x64" }, "sha512-oicJwRlyOoZXVlxmIMaTq7f8pN9QNbdes0q2FXfRsPhfCi8n8JmOZJm5oo1pwDaFbnnD421rVU409M3evFbIqg=="],
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@16.1.6", "", { "os": "win32", "cpu": "arm64" }, "sha512-gQmm8izDTPgs+DCWH22kcDmuUp7NyiJgEl18bcr8irXA5N2m2O+JQIr6f3ct42GOs9c0h8QF3L5SzIxcYAAXXw=="],
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@16.1.6", "", { "os": "win32", "cpu": "x64" }, "sha512-NRfO39AIrzBnixKbjuo2YiYhB6o9d8v/ymU9m/Xk8cyVk+k7XylniXkHwjs4s70wedVffc6bQNbufk5v0xEm0A=="],
"@octokit/auth-token": ["@octokit/auth-token@4.0.0", "", {}, "sha512-tY/msAuJo6ARbK6SPIxZrPBms3xPbfwBrulZe0Wtr/DIY9lje2HeV1uoebShn6mx7SjCHif6EjMvoREj+gZ+SA=="],
"@octokit/core": ["@octokit/core@5.2.2", "", { "dependencies": { "@octokit/auth-token": "^4.0.0", "@octokit/graphql": "^7.1.0", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "@octokit/types": "^13.0.0", "before-after-hook": "^2.2.0", "universal-user-agent": "^6.0.0" } }, "sha512-/g2d4sW9nUDJOMz3mabVQvOGhVa4e/BN/Um7yca9Bb2XTzPPnfTWHWQg+IsEYO7M3Vx+EXvaM/I2pJWIMun1bg=="],
@@ -1018,16 +1129,28 @@
"@opentelemetry/api": ["@opentelemetry/api@1.9.0", "", {}, "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg=="],
"@opentelemetry/api-logs": ["@opentelemetry/api-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-CjruKY9V6NMssL/T1kAFgzosF1v9o6oeN+aX5JB/C/xPNtmgIJqcXHG7fA82Ou1zCpWGl4lROQUKwUNE1pMCyg=="],
"@opentelemetry/context-async-hooks": ["@opentelemetry/context-async-hooks@1.30.1", "", { "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-s5vvxXPVdjqS3kTLKMeBMvop9hbWkwzBpu+mUO2M7sZtlkyDJGwFe33wRKnbaYDo8ExRVBIIdwIGrqpxHuKttA=="],
"@opentelemetry/core": ["@opentelemetry/core@1.30.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "1.28.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-OOCM2C/QIURhJMuKaekP3TRBxBKxG/TWWA0TL2J6nXUtDnuCtccy49LUJF8xPFXMX+0LMcxFpCo8M9cGY1W6rQ=="],
"@opentelemetry/exporter-logs-otlp-http": ["@opentelemetry/exporter-logs-otlp-http@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-exporter-base": "0.208.0", "@opentelemetry/otlp-transformer": "0.208.0", "@opentelemetry/sdk-logs": "0.208.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-jOv40Bs9jy9bZVLo/i8FwUiuCvbjWDI+ZW13wimJm4LjnlwJxGgB+N/VWOZUTpM+ah/awXeQqKdNlpLf2EjvYg=="],
"@opentelemetry/otlp-exporter-base": ["@opentelemetry/otlp-exporter-base@0.208.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/otlp-transformer": "0.208.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-gMd39gIfVb2OgxldxUtOwGJYSH8P1kVFFlJLuut32L6KgUC4gl1dMhn+YC2mGn0bDOiQYSk/uHOdSjuKp58vvA=="],
"@opentelemetry/otlp-transformer": ["@opentelemetry/otlp-transformer@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/sdk-logs": "0.208.0", "@opentelemetry/sdk-metrics": "2.2.0", "@opentelemetry/sdk-trace-base": "2.2.0", "protobufjs": "^7.3.0" }, "peerDependencies": { "@opentelemetry/api": "^1.3.0" } }, "sha512-DCFPY8C6lAQHUNkzcNT9R+qYExvsk6C5Bto2pbNxgicpcSWbe2WHShLxkOxIdNcBiYPdVHv/e7vH7K6TI+C+fQ=="],
"@opentelemetry/propagator-b3": ["@opentelemetry/propagator-b3@1.30.1", "", { "dependencies": { "@opentelemetry/core": "1.30.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-oATwWWDIJzybAZ4pO76ATN5N6FFbOA1otibAVlS8v90B4S1wClnhRUk7K+2CHAwN1JKYuj4jh/lpCEG5BAqFuQ=="],
"@opentelemetry/propagator-jaeger": ["@opentelemetry/propagator-jaeger@1.30.1", "", { "dependencies": { "@opentelemetry/core": "1.30.1" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-Pj/BfnYEKIOImirH76M4hDaBSx6HyZ2CXUqk+Kj02m6BB80c/yo4BdWkn/1gDFfU+YPY+bPR2U0DKBfdxCKwmg=="],
"@opentelemetry/resources": ["@opentelemetry/resources@1.30.1", "", { "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-5UxZqiAgLYGFjS4s9qm5mBVo433u+dSPUFWVWXmLAD4wB65oMCoXaJP1KJa9DIYYMeHu3z4BZcStG3LC593cWA=="],
"@opentelemetry/sdk-logs": ["@opentelemetry/sdk-logs@0.208.0", "", { "dependencies": { "@opentelemetry/api-logs": "0.208.0", "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.4.0 <1.10.0" } }, "sha512-QlAyL1jRpOeaqx7/leG1vJMp84g0xKP6gJmfELBpnI4O/9xPX+Hu5m1POk9Kl+veNkyth5t19hRlN6tNY1sjbA=="],
"@opentelemetry/sdk-metrics": ["@opentelemetry/sdk-metrics@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <1.10.0" } }, "sha512-G5KYP6+VJMZzpGipQw7Giif48h6SGQ2PFKEYCybeXJsOCB4fp8azqMAAzE5lnnHK3ZVwYQrgmFbsUJO/zOnwGw=="],
"@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@1.30.1", "", { "dependencies": { "@opentelemetry/core": "1.30.1", "@opentelemetry/resources": "1.30.1", "@opentelemetry/semantic-conventions": "1.28.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-jVPgBbH1gCy2Lb7X0AVQ8XAfgg0pJ4nvl8/IiQA6nxOsPvS+0zMJaFSs2ltXe0J6C8dqjcnpyqINDJmU30+uOg=="],
"@opentelemetry/sdk-trace-node": ["@opentelemetry/sdk-trace-node@1.30.1", "", { "dependencies": { "@opentelemetry/context-async-hooks": "1.30.1", "@opentelemetry/core": "1.30.1", "@opentelemetry/propagator-b3": "1.30.1", "@opentelemetry/propagator-jaeger": "1.30.1", "@opentelemetry/sdk-trace-base": "1.30.1", "semver": "^7.5.2" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-cBjYOINt1JxXdpw1e5MlHmFRc5fgj4GW/86vsKFxJCJ8AL4PdVtYH41gWwl4qd4uQjqEL1oJVrXkSy5cnduAnQ=="],
@@ -1096,6 +1219,10 @@
"@playwright/test": ["@playwright/test@1.57.0", "", { "dependencies": { "playwright": "1.57.0" }, "bin": { "playwright": "cli.js" } }, "sha512-6TyEnHgd6SArQO8UO2OMTxshln3QMWBtPGrOCgs3wVEmQmwyuNtB10IZMfmYDE0riwNR1cu4q+pPcxMVtaG3TA=="],
"@posthog/core": ["@posthog/core@1.23.1", "", { "dependencies": { "cross-spawn": "^7.0.6" } }, "sha512-GViD5mOv/mcbZcyzz3z9CS0R79JzxVaqEz4sP5Dsea178M/j3ZWe6gaHDZB9yuyGfcmIMQ/8K14yv+7QrK4sQQ=="],
"@posthog/types": ["@posthog/types@1.351.3", "", {}, "sha512-Fuckp/fdL0Ku/kVYljbUdJli8vF07e5+tBsf4GzYBQjfZCGhlT0l37XqVQ05Uk7l/pUDONZD+OOXNBgBzW32gA=="],
"@protobuf-ts/plugin": ["@protobuf-ts/plugin@2.11.1", "", { "dependencies": { "@bufbuild/protobuf": "^2.4.0", "@bufbuild/protoplugin": "^2.4.0", "@protobuf-ts/protoc": "^2.11.1", "@protobuf-ts/runtime": "^2.11.1", "@protobuf-ts/runtime-rpc": "^2.11.1", "typescript": "^3.9" }, "bin": { "protoc-gen-ts": "bin/protoc-gen-ts", "protoc-gen-dump": "bin/protoc-gen-dump" } }, "sha512-HyuprDcw0bEEJqkOWe1rnXUP0gwYLij8YhPuZyZk6cJbIgc/Q0IFgoHQxOXNIXAcXM4Sbehh6kjVnCzasElw1A=="],
"@protobuf-ts/protoc": ["@protobuf-ts/protoc@2.11.1", "", { "bin": { "protoc": "protoc.js" } }, "sha512-mUZJaV0daGO6HUX90o/atzQ6A7bbN2RSuHtdwo8SSF2Qoe3zHwa4IHyCN1evftTeHfLmdz+45qo47sL+5P8nyg=="],
@@ -1104,6 +1231,26 @@
"@protobuf-ts/runtime-rpc": ["@protobuf-ts/runtime-rpc@2.11.1", "", { "dependencies": { "@protobuf-ts/runtime": "^2.11.1" } }, "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ=="],
"@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
"@protobufjs/codegen": ["@protobufjs/codegen@2.0.4", "", {}, "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg=="],
"@protobufjs/eventemitter": ["@protobufjs/eventemitter@1.1.0", "", {}, "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q=="],
"@protobufjs/fetch": ["@protobufjs/fetch@1.1.0", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.1", "@protobufjs/inquire": "^1.1.0" } }, "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ=="],
"@protobufjs/float": ["@protobufjs/float@1.0.2", "", {}, "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ=="],
"@protobufjs/inquire": ["@protobufjs/inquire@1.1.0", "", {}, "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q=="],
"@protobufjs/path": ["@protobufjs/path@1.1.2", "", {}, "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA=="],
"@protobufjs/pool": ["@protobufjs/pool@1.1.0", "", {}, "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw=="],
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.0", "", {}, "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw=="],
"@rollup/rollup-android-arm-eabi": ["@rollup/rollup-android-arm-eabi@4.57.1", "", { "os": "android", "cpu": "arm" }, "sha512-A6ehUVSiSaaliTxai040ZpZ2zTevHYbvu/lDoeAteHI8QnaosIzm4qwtezfRg1jOYaUmnzLX1AOD6Z+UJjtifg=="],
"@rollup/rollup-android-arm64": ["@rollup/rollup-android-arm64@4.57.1", "", { "os": "android", "cpu": "arm64" }, "sha512-dQaAddCY9YgkFHZcFNS/606Exo8vcLHwArFZ7vxXq4rigo2bb494/xKMMwRRQW6ug7Js6yXmBZhSBRuBvCCQ3w=="],
@@ -1340,35 +1487,37 @@
"@storybook/react-dom-shim": ["@storybook/react-dom-shim@10.2.10", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "storybook": "^10.2.10" } }, "sha512-TmBrhyLHn8B8rvDHKk5uW5BqzO1M1T+fqFNWg88NIAJOoyX4Uc90FIJjDuN1OJmWKGwB5vLmPwaKBYsTe1yS+w=="],
"@swc/helpers": ["@swc/helpers@0.5.18", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ=="],
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
"@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
"@tailwindcss/node": ["@tailwindcss/node@4.2.0", "", { "dependencies": { "@jridgewell/remapping": "^2.3.5", "enhanced-resolve": "^5.19.0", "jiti": "^2.6.1", "lightningcss": "1.31.1", "magic-string": "^0.30.21", "source-map-js": "^1.2.1", "tailwindcss": "4.2.0" } }, "sha512-Yv+fn/o2OmL5fh/Ir62VXItdShnUxfpkMA4Y7jdeC8O81WPB8Kf6TT6GSHvnqgSwDzlB5iT7kDpeXxLsUS0T6Q=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.11", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="],
"@tailwindcss/oxide": ["@tailwindcss/oxide@4.2.0", "", { "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.2.0", "@tailwindcss/oxide-darwin-arm64": "4.2.0", "@tailwindcss/oxide-darwin-x64": "4.2.0", "@tailwindcss/oxide-freebsd-x64": "4.2.0", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.2.0", "@tailwindcss/oxide-linux-arm64-gnu": "4.2.0", "@tailwindcss/oxide-linux-arm64-musl": "4.2.0", "@tailwindcss/oxide-linux-x64-gnu": "4.2.0", "@tailwindcss/oxide-linux-x64-musl": "4.2.0", "@tailwindcss/oxide-wasm32-wasi": "4.2.0", "@tailwindcss/oxide-win32-arm64-msvc": "4.2.0", "@tailwindcss/oxide-win32-x64-msvc": "4.2.0" } }, "sha512-AZqQzADaj742oqn2xjl5JbIOzZB/DGCYF/7bpvhA8KvjUj9HJkag6bBuwZvH1ps6dfgxNHyuJVlzSr2VpMgdTQ=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.11", "", { "os": "android", "cpu": "arm64" }, "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg=="],
"@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.2.0", "", { "os": "android", "cpu": "arm64" }, "sha512-F0QkHAVaW/JNBWl4CEKWdZ9PMb0khw5DCELAOnu+RtjAfx5Zgw+gqCHFvqg3AirU1IAd181fwOtJQ5I8Yx5wtw=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ=="],
"@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-I0QylkXsBsJMZ4nkUNSR04p6+UptjcwhcVo3Zu828ikiEqHjVmQL9RuQ6uT/cVIiKpvtVA25msu/eRV97JeNSA=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw=="],
"@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-6TmQIn4p09PBrmnkvbYQ0wbZhLtbaksCDx7Y7R3FYYx0yxNA7xg5KP7dowmQ3d2JVdabIHvs3Hx4K3d5uCf8xg=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA=="],
"@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.2.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-qBudxDvAa2QwGlq9y7VIzhTvp2mLJ6nD/G8/tI70DCDoneaUeLWBJaPcbfzqRIWraj+o969aDQKvKW9dvkUizw=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11", "", { "os": "linux", "cpu": "arm" }, "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg=="],
"@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.2.0", "", { "os": "linux", "cpu": "arm" }, "sha512-7XKkitpy5NIjFZNUQPeUyNJNJn1CJeV7rmMR+exHfTuOsg8rxIO9eNV5TSEnqRcaOK77zQpsyUkBWmPy8FgdSg=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ=="],
"@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-Mff5a5Q3WoQR01pGU1gr29hHM1N93xYrKkGXfPw/aRtK4bOc331Ho4Tgfsm5WDGvpevqMpdlkCojT3qlCQbCpA=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ=="],
"@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-XKcSStleEVnbH6W/9DHzZv1YhjE4eSS6zOu2eRtYAIh7aV4o3vIBs+t/B15xlqoxt6ef/0uiqJVB6hkHjWD/0A=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg=="],
"@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-/hlXCBqn9K6fi7eAM0RsobHwJYa5V/xzWspVTzxnX+Ft9v6n+30Pz8+RxCn7sQL/vRHHLS30iQPrHQunu6/vJA=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
"@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-lKUaygq4G7sWkhQbfdRRBkaq4LY39IriqBQ+Gk6l5nKq6Ay2M2ZZb1tlIyRNgZKS8cbErTwuYSor0IIULC0SHw=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
"@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.2.0", "", { "dependencies": { "@emnapi/core": "^1.8.1", "@emnapi/runtime": "^1.8.1", "@emnapi/wasi-threads": "^1.1.0", "@napi-rs/wasm-runtime": "^1.1.1", "@tybys/wasm-util": "^0.10.1", "tslib": "^2.8.1" }, "cpu": "none" }, "sha512-xuDjhAsFdUuFP5W9Ze4k/o4AskUtI8bcAGU4puTYprr89QaYFmhYOPfP+d1pH+k9ets6RoE23BXZM1X1jJqoyw=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
"@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.2.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-2UU/15y1sWDEDNJXxEIrfWKC2Yb4YgIW5Xz2fKFqGzFWfoMHWFlfa1EJlGO2Xzjkq/tvSarh9ZTjvbxqWvLLXA=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.11", "", { "os": "win32", "cpu": "x64" }, "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg=="],
"@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.2.0", "", { "os": "win32", "cpu": "x64" }, "sha512-CrFadmFoc+z76EV6LPG1jx6XceDsaCG3lFhyLNo/bV9ByPrE+FnBPckXQVP4XRkN76h3Fjt/a+5Er/oA/nCBvQ=="],
"@tailwindcss/postcss": ["@tailwindcss/postcss@4.2.0", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "@tailwindcss/node": "4.2.0", "@tailwindcss/oxide": "4.2.0", "postcss": "^8.5.6", "tailwindcss": "4.2.0" } }, "sha512-u6YBacGpOm/ixPfKqfgrJEjMfrYmPD7gEFRoygS/hnQaRtV0VCBdpkx5Ouw9pnaLRwwlgGCuJw8xLpaR0hOrQg=="],
"@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="],
@@ -1464,10 +1613,16 @@
"@types/katex": ["@types/katex@0.16.7", "", {}, "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ=="],
"@types/linkify-it": ["@types/linkify-it@3.0.5", "", {}, "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw=="],
"@types/luxon": ["@types/luxon@3.7.1", "", {}, "sha512-H3iskjFIAn5SlJU7OuxUmTEpebK6TKB8rxZShDslBMZJ5u9S//KM1sbdAisiSrqwLQncVjnpi2OK2J51h+4lsg=="],
"@types/markdown-it": ["@types/markdown-it@12.2.3", "", { "dependencies": { "@types/linkify-it": "*", "@types/mdurl": "*" } }, "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ=="],
"@types/mdast": ["@types/mdast@4.0.4", "", { "dependencies": { "@types/unist": "*" } }, "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA=="],
"@types/mdurl": ["@types/mdurl@2.0.0", "", {}, "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg=="],
"@types/mdx": ["@types/mdx@2.0.13", "", {}, "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw=="],
"@types/mocha": ["@types/mocha@10.0.10", "", {}, "sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q=="],
@@ -1480,6 +1635,8 @@
"@types/react": ["@types/react@19.2.14", "", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
"@types/react-dom": ["@types/react-dom@19.2.3", "", { "peerDependencies": { "@types/react": "^19.2.0" } }, "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ=="],
"@types/trusted-types": ["@types/trusted-types@2.0.7", "", {}, "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw=="],
"@types/tunnel": ["@types/tunnel@0.0.3", "", { "dependencies": { "@types/node": "*" } }, "sha512-sOUTGn6h1SfQ+gbgqC364jLFBw2lnFqkgF3q0WovEHRLMrVD1sd5aufqi/aJObLekJO+Aq5z646U4Oxy6shXMA=="],
@@ -1544,12 +1701,20 @@
"@vitest/expect": ["@vitest/expect@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "tinyrainbow": "^2.0.0" } }, "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig=="],
"@vitest/mocker": ["@vitest/mocker@3.2.4", "", { "dependencies": { "@vitest/spy": "3.2.4", "estree-walker": "^3.0.3", "magic-string": "^0.30.17" }, "peerDependencies": { "msw": "^2.4.9", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "optionalPeers": ["msw", "vite"] }, "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ=="],
"@vitest/pretty-format": ["@vitest/pretty-format@3.2.4", "", { "dependencies": { "tinyrainbow": "^2.0.0" } }, "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA=="],
"@vitest/runner": ["@vitest/runner@3.2.4", "", { "dependencies": { "@vitest/utils": "3.2.4", "pathe": "^2.0.3", "strip-literal": "^3.0.0" } }, "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ=="],
"@vitest/snapshot": ["@vitest/snapshot@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "magic-string": "^0.30.17", "pathe": "^2.0.3" } }, "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ=="],
"@vitest/spy": ["@vitest/spy@3.2.4", "", { "dependencies": { "tinyspy": "^4.0.3" } }, "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw=="],
"@vitest/utils": ["@vitest/utils@3.2.4", "", { "dependencies": { "@vitest/pretty-format": "3.2.4", "loupe": "^3.1.4", "tinyrainbow": "^2.0.0" } }, "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA=="],
"@vscode/codicons": ["@vscode/codicons@0.0.44", "", {}, "sha512-F7qPRumUK3EHjNdopfICLGRf3iNPoZQt+McTHAn4AlOWPB3W2kL4H0S7uqEqbyZ6rCxaeDjpAn3MCUnwTu/VJQ=="],
"@vscode/test-cli": ["@vscode/test-cli@0.0.12", "", { "dependencies": { "@types/mocha": "^10.0.10", "c8": "^10.1.3", "chokidar": "^3.6.0", "enhanced-resolve": "^5.18.3", "glob": "^10.3.10", "minimatch": "^9.0.3", "mocha": "^11.7.4", "supports-color": "^10.2.2", "yargs": "^17.7.2" }, "bin": { "vscode-test": "out/bin.mjs" } }, "sha512-iYN0fDg29+a2Xelle/Y56Xvv7Nc8Thzq4VwpzAF/SIE6918rDicqfsQxV6w1ttr2+SOm+10laGuY9FG2ptEKsQ=="],
"@vscode/test-electron": ["@vscode/test-electron@2.5.2", "", { "dependencies": { "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.5", "jszip": "^3.10.1", "ora": "^8.1.0", "semver": "^7.6.2" } }, "sha512-8ukpxv4wYe0iWMRQU18jhzJOHkeGKbnw7xWRX3Zw1WJA4cEKbHcmmLPdPrPtL6rhDcrlCZN+xKRpv09n4gRHYg=="],
@@ -1596,7 +1761,7 @@
"arctic": ["arctic@2.3.4", "", { "dependencies": { "@oslojs/crypto": "1.0.1", "@oslojs/encoding": "1.1.0", "@oslojs/jwt": "0.2.0" } }, "sha512-+p30BOWsctZp+CVYCt7oAean/hWGW42sH5LAcRQX56ttEkFJWbzXBhmSpibbzwSJkRrotmsA+oAoJoVsU0f5xA=="],
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"aria-query": ["aria-query@5.3.2", "", {}, "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="],
@@ -1610,6 +1775,8 @@
"atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
"autoprefixer": ["autoprefixer@10.4.24", "", { "dependencies": { "browserslist": "^4.28.1", "caniuse-lite": "^1.0.30001766", "fraction.js": "^5.3.4", "picocolors": "^1.1.1", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": { "autoprefixer": "bin/autoprefixer" } }, "sha512-uHZg7N9ULTVbutaIsDRoUkoS8/h3bdsmVJYZ5l3wv8Cp/6UIIoRDm90hZ+BwxUj/hGBEzLxdHNSKuFpn8WOyZw=="],
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
"avvio": ["avvio@9.1.0", "", { "dependencies": { "@fastify/error": "^4.0.0", "fastq": "^1.17.1" } }, "sha512-fYASnYi600CsH/j9EQov7lECAniYiBFiiAtBNuZYLA2leLe9qOvZzqYHFjtIj6gD2VMoMLP14834LFWvr4IfDw=="],
@@ -1702,6 +1869,8 @@
"c8": ["c8@10.1.3", "", { "dependencies": { "@bcoe/v8-coverage": "^1.0.1", "@istanbuljs/schema": "^0.1.3", "find-up": "^5.0.0", "foreground-child": "^3.1.1", "istanbul-lib-coverage": "^3.2.0", "istanbul-lib-report": "^3.0.1", "istanbul-reports": "^3.1.6", "test-exclude": "^7.0.1", "v8-to-istanbul": "^9.0.0", "yargs": "^17.7.2", "yargs-parser": "^21.1.1" }, "peerDependencies": { "monocart-coverage-reports": "^2" }, "optionalPeers": ["monocart-coverage-reports"], "bin": { "c8": "bin/c8.js" } }, "sha512-LvcyrOAaOnrrlMpW22n690PUvxiq4Uf9WMhQwNJ9vgagkL/ph1+D4uvjvDA5XCbykrc0sx+ay6pVi9YZ1GnhyA=="],
"cac": ["cac@6.7.14", "", {}, "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ=="],
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
@@ -1738,6 +1907,8 @@
"cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="],
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
"clipboardy": ["clipboardy@4.0.0", "", { "dependencies": { "execa": "^8.0.1", "is-wsl": "^3.1.0", "is64bit": "^2.0.0" } }, "sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w=="],
"cliui": ["cliui@9.0.1", "", { "dependencies": { "string-width": "^7.2.0", "strip-ansi": "^7.1.0", "wrap-ansi": "^9.0.0" } }, "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w=="],
@@ -1772,6 +1943,8 @@
"cookie-signature": ["cookie-signature@1.2.2", "", {}, "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg=="],
"core-js": ["core-js@3.48.0", "", {}, "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ=="],
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
"cors": ["cors@2.8.6", "", { "dependencies": { "object-assign": "^4", "vary": "^1" } }, "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw=="],
@@ -1874,6 +2047,8 @@
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
@@ -1906,6 +2081,8 @@
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
@@ -1924,6 +2101,8 @@
"exif-parser": ["exif-parser@0.1.12", "", {}, "sha512-c2bQfLNbMzLPmzQuOr8fy0csy84WmwnER81W88DzTp9CYNPJ6yzOj2EZAh9pywYpqHnshVLHQJ8WzldAyfY+Iw=="],
"expect-type": ["expect-type@1.3.0", "", {}, "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA=="],
"express": ["express@5.2.1", "", { "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", "finalhandler": "^2.1.0", "fresh": "^2.0.0", "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", "mime-types": "^3.0.0", "on-finished": "^2.4.1", "once": "^1.4.0", "parseurl": "^1.3.3", "proxy-addr": "^2.0.7", "qs": "^6.14.0", "range-parser": "^1.2.1", "router": "^2.2.0", "send": "^1.1.0", "serve-static": "^2.2.0", "statuses": "^2.0.1", "type-is": "^2.0.1", "vary": "^1.1.2" } }, "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw=="],
"express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="],
@@ -1966,6 +2145,8 @@
"fetch-blob": ["fetch-blob@3.2.0", "", { "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" } }, "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ=="],
"fflate": ["fflate@0.4.8", "", {}, "sha512-FJqqoDBR00Mdj9ppamLa/Y7vxm+PRmNWA67N846RvsoYVMKB4q3y/de5PA7gUmRMYK/8CMz2GDZQmCRN1wBcWA=="],
"file-entry-cache": ["file-entry-cache@8.0.0", "", { "dependencies": { "flat-cache": "^4.0.0" } }, "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ=="],
"file-type": ["file-type@16.5.4", "", { "dependencies": { "readable-web-to-node-stream": "^3.0.0", "strtok3": "^6.2.4", "token-types": "^4.1.1" } }, "sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw=="],
@@ -2002,6 +2183,8 @@
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
"fraction.js": ["fraction.js@5.3.4", "", {}, "sha512-1X1NTtiJphryn/uLQz3whtY6jK3fTqoE3ohKs0tT+Ujr1W59oopxmoEh7Lu5p6vBaPbgoM0bzveAW4Qi5RyWDQ=="],
"fresh": ["fresh@2.0.0", "", {}, "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A=="],
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
@@ -2194,7 +2377,7 @@
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
@@ -2244,6 +2427,8 @@
"lightningcss": ["lightningcss@1.30.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-darwin-arm64": "1.30.1", "lightningcss-darwin-x64": "1.30.1", "lightningcss-freebsd-x64": "1.30.1", "lightningcss-linux-arm-gnueabihf": "1.30.1", "lightningcss-linux-arm64-gnu": "1.30.1", "lightningcss-linux-arm64-musl": "1.30.1", "lightningcss-linux-x64-gnu": "1.30.1", "lightningcss-linux-x64-musl": "1.30.1", "lightningcss-win32-arm64-msvc": "1.30.1", "lightningcss-win32-x64-msvc": "1.30.1" } }, "sha512-xi6IyHML+c9+Q3W0S4fCQJOym42pyurFiJUHEcEyHS0CeKzia4yZDEsLlqOFykxOdHpNy0NmvVO31vcSqAxJCg=="],
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.31.1", "", { "os": "android", "cpu": "arm64" }, "sha512-HXJF3x8w9nQ4jbXRiNppBCqeZPIAfUo8zE/kOEGbW5NZvGc/K7nMxbhIr+YlFlHW5mpbg/YFPdbnCh1wAXCKFg=="],
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.30.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-c8JK7hyE65X1MHMN+Viq9n11RRC7hgin3HhYKhrMyaXflk5GVplZ60IxyoVtzILeKr+xAJwg6zK6sjTBJ0FKYQ=="],
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.30.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-k1EvjakfumAQoTfcXUcHQZhSpLlkAuEkdMBsI/ivWw9hL+7FtilQc0Cy3hrx0AAQrVtQAbMI7YjCgYgvn37PzA=="],
@@ -2272,6 +2457,8 @@
"log-symbols": ["log-symbols@4.1.0", "", { "dependencies": { "chalk": "^4.1.0", "is-unicode-supported": "^0.1.0" } }, "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg=="],
"long": ["long@5.3.2", "", {}, "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA=="],
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": { "loose-envify": "cli.js" } }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
"loupe": ["loupe@3.2.1", "", {}, "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ=="],
@@ -2358,6 +2545,8 @@
"negotiator": ["negotiator@1.0.0", "", {}, "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg=="],
"next": ["next@16.1.6", "", { "dependencies": { "@next/env": "16.1.6", "@swc/helpers": "0.5.15", "baseline-browser-mapping": "^2.8.3", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "16.1.6", "@next/swc-darwin-x64": "16.1.6", "@next/swc-linux-arm64-gnu": "16.1.6", "@next/swc-linux-arm64-musl": "16.1.6", "@next/swc-linux-x64-gnu": "16.1.6", "@next/swc-linux-x64-musl": "16.1.6", "@next/swc-win32-arm64-msvc": "16.1.6", "@next/swc-win32-x64-msvc": "16.1.6", "sharp": "^0.34.4" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-hkyRkcu5x/41KoqnROkfTm2pZVbKxvbZRuNvKXLRXxs3VfyO0WhY50TQS40EuKO9SW3rBj/sF3WbVwDACeMZyw=="],
"node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
"node-domexception": ["node-domexception@1.0.0", "", {}, "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ=="],
@@ -2492,16 +2681,24 @@
"postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="],
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
"posthog-js": ["posthog-js@1.351.3", "", { "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/api-logs": "^0.208.0", "@opentelemetry/exporter-logs-otlp-http": "^0.208.0", "@opentelemetry/resources": "^2.2.0", "@opentelemetry/sdk-logs": "^0.208.0", "@posthog/core": "1.23.1", "@posthog/types": "1.351.3", "core-js": "^3.38.1", "dompurify": "^3.3.1", "fflate": "^0.4.8", "preact": "^10.28.2", "query-selector-shadow-dom": "^1.0.1", "web-vitals": "^5.1.0" } }, "sha512-c2sQOhbo0Ed2Cgq+gTMFiArneu2/+HTf6sJdHw60oj2BIXTHjQfGY7H2XzA7ZZHsDNVVVcpsqpxrUhyzGsfDhQ=="],
"posthog-node": ["posthog-node@4.4.0", "", { "dependencies": { "axios": "^1.7.4" } }, "sha512-4FEFBuc4FDFkTEiCSIo7DFV0jpprlqfR/SzjVgg7E2rRvfxTW4J47IvCwSCo5C9lBeV0ujDubY/YArHG37aJIw=="],
"powershell-utils": ["powershell-utils@0.1.0", "", {}, "sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A=="],
"preact": ["preact@10.28.4", "", {}, "sha512-uKFfOHWuSNpRFVTnljsCluEFq57OKT+0QdOiQo8XWnQ/pSvg7OpX5eNOejELXJMWy+BwM2nobz0FkvzmnpCNsQ=="],
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
"prettier": ["prettier@3.6.2", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ=="],
"pretty-format": ["pretty-format@27.5.1", "", { "dependencies": { "ansi-regex": "^5.0.1", "ansi-styles": "^5.0.0", "react-is": "^17.0.1" } }, "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ=="],
"prismjs": ["prismjs@1.30.0", "", {}, "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw=="],
"process": ["process@0.11.10", "", {}, "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A=="],
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
@@ -2510,6 +2707,8 @@
"property-information": ["property-information@7.1.0", "", {}, "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ=="],
"protobufjs": ["protobufjs@7.5.4", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.4", "@protobufjs/eventemitter": "^1.1.0", "@protobufjs/fetch": "^1.1.0", "@protobufjs/float": "^1.0.2", "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.0", "@types/node": ">=13.7.0", "long": "^5.0.0" } }, "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg=="],
"proxy-addr": ["proxy-addr@2.0.7", "", { "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" } }, "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg=="],
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
@@ -2522,6 +2721,8 @@
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
"query-selector-shadow-dom": ["query-selector-shadow-dom@1.0.1", "", {}, "sha512-lT5yCqEBgfoMYpf3F2xQRK7zEr1rhIIZuceDK6+xRkJQ4NMbHTwXqk4NkwDwQMNqXgG9r9fyHnzwNVs6zV5KRw=="],
"querystring": ["querystring@0.2.0", "", {}, "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g=="],
"quick-format-unescaped": ["quick-format-unescaped@4.0.4", "", {}, "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg=="],
@@ -2536,11 +2737,11 @@
"rc9": ["rc9@2.1.2", "", { "dependencies": { "defu": "^6.1.4", "destr": "^2.0.3" } }, "sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg=="],
"react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="],
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
"react-docgen-typescript": ["react-docgen-typescript@2.4.0", "", { "peerDependencies": { "typescript": ">= 4.3.x" } }, "sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg=="],
"react-dom": ["react-dom@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="],
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
"react-is": ["react-is@17.0.2", "", {}, "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="],
@@ -2608,7 +2809,7 @@
"sax": ["sax@1.2.1", "", {}, "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA=="],
"scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
"section-matter": ["section-matter@1.0.0", "", { "dependencies": { "extend-shallow": "^2.0.1", "kind-of": "^6.0.0" } }, "sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA=="],
@@ -2636,6 +2837,8 @@
"setprototypeof": ["setprototypeof@1.2.0", "", {}, "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw=="],
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
@@ -2650,6 +2853,8 @@
"side-channel-weakmap": ["side-channel-weakmap@1.0.2", "", { "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", "get-intrinsic": "^1.2.5", "object-inspect": "^1.13.3", "side-channel-map": "^1.0.1" } }, "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A=="],
"siginfo": ["siginfo@2.0.0", "", {}, "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g=="],
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"simple-git": ["simple-git@3.31.1", "", { "dependencies": { "@kwsites/file-exists": "^1.1.1", "@kwsites/promise-deferred": "^1.1.1", "debug": "^4.4.0" } }, "sha512-oiWP4Q9+kO8q9hHqkX35uuHmxiEbZNTrZ5IPxgMGrJwN76pzjm/jabkZO0ItEcqxAincqGAzL3QHSaHt4+knBg=="],
@@ -2704,10 +2909,14 @@
"sst-win32-x86": ["sst-win32-x86@3.17.23", "", { "os": "win32", "cpu": "none" }, "sha512-DIp3s54IpNAfdYjSRt6McvkbEPQDMxUu6RUeRAd2C+FcTJgTloon/ghAPQBaDgu2VoVgymjcJARO/XyfKcCLOQ=="],
"stackback": ["stackback@0.0.2", "", {}, "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw=="],
"stage-js": ["stage-js@1.0.0-alpha.23", "", {}, "sha512-eH+X90SrOx394tVJjYu/ld6wwMdcWzDa1xU0FinTppef7fmPvvtxoCWsDtTCEtKA/sHnPslwyEy6ATGUWLYKXA=="],
"statuses": ["statuses@2.0.2", "", {}, "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw=="],
"std-env": ["std-env@3.10.0", "", {}, "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg=="],
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
"storybook": ["storybook@10.2.10", "", { "dependencies": { "@storybook/global": "^5.0.0", "@storybook/icons": "^2.0.1", "@testing-library/jest-dom": "^6.6.3", "@testing-library/user-event": "^14.6.1", "@vitest/expect": "3.2.4", "@vitest/spy": "3.2.4", "esbuild": "^0.18.0 || ^0.19.0 || ^0.20.0 || ^0.21.0 || ^0.22.0 || ^0.23.0 || ^0.24.0 || ^0.25.0 || ^0.26.0 || ^0.27.0", "open": "^10.2.0", "recast": "^0.23.5", "semver": "^7.7.3", "use-sync-external-store": "^1.5.0", "ws": "^8.18.0" }, "peerDependencies": { "prettier": "^2 || ^3" }, "optionalPeers": ["prettier"], "bin": "./dist/bin/dispatcher.js" }, "sha512-N4U42qKgzMHS7DjqLz5bY4P7rnvJtYkWFCyKspZr3FhPUuy6CWOae3aYC2BjXkHrdug0Jyta6VxFTuB1tYUKhg=="],
@@ -2736,17 +2945,21 @@
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"strip-literal": ["strip-literal@3.1.0", "", { "dependencies": { "js-tokens": "^9.0.1" } }, "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg=="],
"strnum": ["strnum@2.1.2", "", {}, "sha512-l63NF9y/cLROq/yqKXSLtcMeeyOfnSQlfMSlzFt/K73oIaD8DGaQWd7Z34X9GPiKqP5rbSh84Hl4bOlLcjiSrQ=="],
"strtok3": ["strtok3@6.3.0", "", { "dependencies": { "@tokenizer/token": "^0.3.0", "peek-readable": "^4.1.0" } }, "sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw=="],
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
"supports-color": ["supports-color@10.2.2", "", {}, "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g=="],
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"system-architecture": ["system-architecture@0.1.0", "", {}, "sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA=="],
"tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
"tailwindcss": ["tailwindcss@4.2.0", "", {}, "sha512-yYzTZ4++b7fNYxFfpnberEEKu43w44aqDMNM9MHMmcKuCH7lL8jJ4yJ7LGHv7rSwiqM0nkiobF9I6cLlpS2P7Q=="],
"tapable": ["tapable@2.3.0", "", {}, "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg=="],
@@ -2768,12 +2981,16 @@
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tinybench": ["tinybench@2.9.0", "", {}, "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg=="],
"tinycolor2": ["tinycolor2@1.6.0", "", {}, "sha512-XPaBkWQJdsf3pLKJV9p4qN/S+fm2Oj8AIPo1BTUhg5oxkvm9+SVEGFdhyOz7tTdUTfvxMiAs4sp6/eZO2Ew+pw=="],
"tinyexec": ["tinyexec@0.3.2", "", {}, "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA=="],
"tinyglobby": ["tinyglobby@0.2.15", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.3" } }, "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ=="],
"tinypool": ["tinypool@1.1.1", "", {}, "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg=="],
"tinyrainbow": ["tinyrainbow@2.0.0", "", {}, "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw=="],
"tinyspy": ["tinyspy@4.0.4", "", {}, "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q=="],
@@ -2882,12 +3099,16 @@
"vite": ["vite@7.3.1", "", { "dependencies": { "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA=="],
"vite-node": ["vite-node@3.2.4", "", { "dependencies": { "cac": "^6.7.14", "debug": "^4.4.1", "es-module-lexer": "^1.7.0", "pathe": "^2.0.3", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0" }, "bin": { "vite-node": "vite-node.mjs" } }, "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg=="],
"vite-plugin-icons-spritesheet": ["vite-plugin-icons-spritesheet@3.0.1", "", { "dependencies": { "chalk": "^5.4.1", "glob": "^11.0.1", "node-html-parser": "^7.0.1", "tinyexec": "^0.3.2" }, "peerDependencies": { "vite": ">=5.2.0" } }, "sha512-Cr0+Z6wRMwSwKisWW9PHeTjqmQFv0jwRQQMc3YgAhAgZEe03j21el0P/CA31KN/L5eiL1LhR14VTXl96LetonA=="],
"vite-plugin-solid": ["vite-plugin-solid@2.11.10", "", { "dependencies": { "@babel/core": "^7.23.3", "@types/babel__core": "^7.20.4", "babel-preset-solid": "^1.8.4", "merge-anything": "^5.1.7", "solid-refresh": "^0.6.3", "vitefu": "^1.0.4" }, "peerDependencies": { "@testing-library/jest-dom": "^5.16.6 || ^5.17.0 || ^6.*", "solid-js": "^1.7.2", "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" }, "optionalPeers": ["@testing-library/jest-dom"] }, "sha512-Yr1dQybmtDtDAHkii6hXuc1oVH9CPcS/Zb2jN/P36qqcrkNnVPsMTzQ06jyzFPFjj3U1IYKMVt/9ZqcwGCEbjw=="],
"vitefu": ["vitefu@1.1.1", "", { "peerDependencies": { "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0" }, "optionalPeers": ["vite"] }, "sha512-B/Fegf3i8zh0yFbpzZ21amWzHmuNlLlmJT6n7bu5e+pCHUKQIfXSYokrqOBGEMMe9UG2sostKQF9mml/vYaWJQ=="],
"vitest": ["vitest@3.2.4", "", { "dependencies": { "@types/chai": "^5.2.2", "@vitest/expect": "3.2.4", "@vitest/mocker": "3.2.4", "@vitest/pretty-format": "^3.2.4", "@vitest/runner": "3.2.4", "@vitest/snapshot": "3.2.4", "@vitest/spy": "3.2.4", "@vitest/utils": "3.2.4", "chai": "^5.2.0", "debug": "^4.4.1", "expect-type": "^1.2.1", "magic-string": "^0.30.17", "pathe": "^2.0.3", "picomatch": "^4.0.2", "std-env": "^3.9.0", "tinybench": "^2.9.0", "tinyexec": "^0.3.2", "tinyglobby": "^0.2.14", "tinypool": "^1.1.1", "tinyrainbow": "^2.0.0", "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0", "vite-node": "3.2.4", "why-is-node-running": "^2.3.0" }, "peerDependencies": { "@edge-runtime/vm": "*", "@types/debug": "^4.1.12", "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "@vitest/browser": "3.2.4", "@vitest/ui": "3.2.4", "happy-dom": "*", "jsdom": "*" }, "optionalPeers": ["@edge-runtime/vm", "@types/debug", "@types/node", "@vitest/browser", "@vitest/ui", "happy-dom", "jsdom"], "bin": { "vitest": "vitest.mjs" } }, "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A=="],
"vscode-jsonrpc": ["vscode-jsonrpc@8.2.1", "", {}, "sha512-kdjOSJ2lLIn7r1rtrMbbNCHjyMPfRnowdKjBQ+mGq6NAW5QY2bEZC/khaC5OR8svbbjvLEaIXkOq45e2X9BIbQ=="],
"vscode-languageserver-types": ["vscode-languageserver-types@3.17.5", "", {}, "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="],
@@ -2896,6 +3117,8 @@
"web-tree-sitter": ["web-tree-sitter@0.25.10", "", { "peerDependencies": { "@types/emscripten": "^1.40.0" }, "optionalPeers": ["@types/emscripten"] }, "sha512-Y09sF44/13XvgVKgO2cNDw5rGk6s26MgoZPXLESvMXeefBf7i6/73eFurre0IsTW6E14Y0ArIzhUMmjoc7xyzA=="],
"web-vitals": ["web-vitals@5.1.0", "", {}, "sha512-ArI3kx5jI0atlTtmV0fWU3fjpLmq/nD3Zr1iFFlJLaqa5wLBkUSzINwBPySCX/8jRyjlmy1Volw1kz1g9XE4Jg=="],
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
@@ -3002,8 +3225,6 @@
"@eslint/eslintrc/ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"@eslint/eslintrc/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"@eslint/eslintrc/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"@gitlab/gitlab-ai-provider/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.71.2", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-TGNDEUuEstk/DKu0/TflXAEt+p+p/WhTlFzEnoosvbaDU2LTjm42igSdlL0VijrKpWejtOKxX0b8A7uc+XiSAQ=="],
@@ -3012,14 +3233,16 @@
"@gitlab/gitlab-ai-provider/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"@hey-api/json-schema-ref-parser/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"@hey-api/openapi-ts/open": ["open@11.0.0", "", { "dependencies": { "default-browser": "^5.4.0", "define-lazy-prop": "^3.0.0", "is-in-ssh": "^1.0.0", "is-inside-container": "^1.0.0", "powershell-utils": "^0.1.0", "wsl-utils": "^0.3.0" } }, "sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw=="],
"@hey-api/openapi-ts/semver": ["semver@7.7.3", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q=="],
"@hono/zod-validator/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
"@internationalized/date/@swc/helpers": ["@swc/helpers@0.5.18", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ=="],
"@internationalized/number/@swc/helpers": ["@swc/helpers@0.5.18", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-TXTnIcNJQEKwThMMqBXsZ4VGAza6bvN4pa41Rkqoio6QBKMvo+5lexeTMScGCIxtzgQJzElcvIltani+adC5PQ=="],
"@isaacs/cliui/string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
"@isaacs/cliui/wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
@@ -3060,6 +3283,8 @@
"@joshwooding/vite-plugin-react-docgen-typescript/glob": ["glob@13.0.5", "", { "dependencies": { "minimatch": "^10.2.1", "minipass": "^7.1.2", "path-scurry": "^2.0.0" } }, "sha512-BzXxZg24Ibra1pbQ/zE7Kys4Ua1ks7Bn6pKLkVPZ9FZe4JQS6/Q7ef3LG1H+k7lUf5l4T3PLSyYyYJVYUvfgTw=="],
"@kilocode/kilo-docs/typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"@kilocode/kilo-gateway/@openrouter/ai-sdk-provider": ["@openrouter/ai-sdk-provider@1.5.2", "", { "dependencies": { "@openrouter/sdk": "^0.1.27" }, "peerDependencies": { "@toon-format/toon": "^2.0.0", "ai": "^5.0.0", "zod": "^3.24.1 || ^v4" }, "optionalPeers": ["@toon-format/toon"] }, "sha512-3Th0vmJ9pjnwcPc2H1f59Mb0LFvwaREZAScfOQIpUxAHjZ7ZawVKDP27qgsteZPmMYqccNMy4r4Y3kgUnNcKAg=="],
"@kilocode/kilo-gateway/@opentui/core": ["@opentui/core@0.1.75", "", { "dependencies": { "bun-ffi-structs": "0.1.2", "diff": "8.0.2", "jimp": "1.6.0", "marked": "17.0.1", "yoga-layout": "3.2.1" }, "optionalDependencies": { "@dimforge/rapier2d-simd-compat": "^0.17.3", "@opentui/core-darwin-arm64": "0.1.75", "@opentui/core-darwin-x64": "0.1.75", "@opentui/core-linux-arm64": "0.1.75", "@opentui/core-linux-x64": "0.1.75", "@opentui/core-win32-arm64": "0.1.75", "@opentui/core-win32-x64": "0.1.75", "bun-webgpu": "0.1.4", "planck": "^1.4.2", "three": "0.177.0" }, "peerDependencies": { "web-tree-sitter": "0.25.10" } }, "sha512-8ARRZxSG+BXkJmEVtM2DQ4se7DAF1ZCKD07d+AklgTr2mxCzmdxxPbOwRzboSQ6FM7qGuTVPVbV4O2W9DpUmoA=="],
@@ -3110,6 +3335,8 @@
"@openauthjs/openauth/jose": ["jose@5.9.6", "", {}, "sha512-AMlnetc9+CV9asI19zHmrgS/WYsWUwCn2R7RzlbJWD7F9eWYUTGyBmU9o6PxngtLGOiDGPRu+Uc4fhKzbpteZQ=="],
"@opencode-ai/app/tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
"@opencode-ai/app/vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="],
"@opencode-ai/desktop/@actions/artifact": ["@actions/artifact@4.0.0", "", { "dependencies": { "@actions/core": "^1.10.0", "@actions/github": "^6.0.1", "@actions/http-client": "^2.1.0", "@azure/core-http": "^3.0.5", "@azure/storage-blob": "^12.15.0", "@octokit/core": "^5.2.1", "@octokit/plugin-request-log": "^1.0.4", "@octokit/plugin-retry": "^3.0.9", "@octokit/request": "^8.4.1", "@octokit/request-error": "^5.1.1", "@protobuf-ts/plugin": "^2.2.3-alpha.1", "archiver": "^7.0.1", "jwt-decode": "^3.1.2", "unzip-stream": "^0.3.1" } }, "sha512-HCc2jMJRAfviGFAh0FsOR/jNfWhirxl7W6z8zDtttt0GltwxBLdEIjLiweOPFl9WbyJRW1VWnPUSAixJqcWUMQ=="],
@@ -3118,8 +3345,28 @@
"@opencode-ai/desktop/vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="],
"@opencode-ai/ui/tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
"@opencode-ai/ui/vite": ["vite@7.1.4", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.14" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-X5QFK4SGynAeeIt+A7ZWnApdUyHYm+pzv/8/A57LqSGcI88U6R6ipOs3uCesdc6yl7nl+zNO0t8LmqAdXcQihw=="],
"@opentelemetry/exporter-logs-otlp-http/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
"@opentelemetry/otlp-exporter-base/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
"@opentelemetry/otlp-transformer/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
"@opentelemetry/otlp-transformer/@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="],
"@opentelemetry/otlp-transformer/@opentelemetry/sdk-trace-base": ["@opentelemetry/sdk-trace-base@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/resources": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-xWQgL0Bmctsalg6PaXExmzdedSp3gyKV8mQBwK/j9VGdCDu2fmXIb2gAehBKbkXCpJ4HPkgv3QfoJWRT4dHWbw=="],
"@opentelemetry/sdk-logs/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
"@opentelemetry/sdk-logs/@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="],
"@opentelemetry/sdk-metrics/@opentelemetry/core": ["@opentelemetry/core@2.2.0", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-FuabnnUm8LflnieVxs6eP7Z383hgQU4W1e3KJS6aOG3RxWxcHyBxH8fDMHNgu/gFx/M2jvTOW/4/PHhLz6bjWw=="],
"@opentelemetry/sdk-metrics/@opentelemetry/resources": ["@opentelemetry/resources@2.2.0", "", { "dependencies": { "@opentelemetry/core": "2.2.0", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-1pNQf/JazQTMA0BiO5NINUzH0cbLbbl7mntLa4aJNmCCXSj0q03T5ZXXL0zw4G55TjdL9Tz32cznGClf+8zr5A=="],
"@opentui/solid/@babel/core": ["@babel/core@7.28.0", "", { "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.0", "@babel/helper-compilation-targets": "^7.27.2", "@babel/helper-module-transforms": "^7.27.3", "@babel/helpers": "^7.27.6", "@babel/parser": "^7.28.0", "@babel/template": "^7.27.2", "@babel/traverse": "^7.28.0", "@babel/types": "^7.28.0", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.3", "semver": "^6.3.1" } }, "sha512-UlLAnTPrFdNGoFtbSXwcGFQBtQZJCNjaN6hQNP3UPvuNXT1i82N26KL3dZeIpNalWywr9IuQuncaAfUaS1g6sQ=="],
"@opentui/solid/solid-js": ["solid-js@1.9.11", "", { "dependencies": { "csstype": "^3.1.0", "seroval": "~1.5.0", "seroval-plugins": "~1.5.0" } }, "sha512-WEJtcc5mkh/BnHA6Yrg4whlF8g6QwpmXXRg4P2ztPmcKeHHlH4+djYecBLhSpecZY2RRECXYUwIc/C2r3yzQ4Q=="],
@@ -3142,7 +3389,11 @@
"@smithy/eventstream-serde-universal/@smithy/eventstream-codec": ["@smithy/eventstream-codec@4.2.8", "", { "dependencies": { "@aws-crypto/crc32": "5.2.0", "@smithy/types": "^4.12.0", "@smithy/util-hex-encoding": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-jS/O5Q14UsufqoGhov7dHLOPCzkYJl9QDzusI2Psh4wyYx/izhzvX9P4D69aTxcdfVhEPhjK+wYyn/PzLjKbbw=="],
"@tailwindcss/oxide/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"@storybook/addon-docs/react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="],
"@storybook/addon-docs/react-dom": ["react-dom@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="],
"@tailwindcss/node/lightningcss": ["lightningcss@1.31.1", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.31.1", "lightningcss-darwin-arm64": "1.31.1", "lightningcss-darwin-x64": "1.31.1", "lightningcss-freebsd-x64": "1.31.1", "lightningcss-linux-arm-gnueabihf": "1.31.1", "lightningcss-linux-arm64-gnu": "1.31.1", "lightningcss-linux-arm64-musl": "1.31.1", "lightningcss-linux-x64-gnu": "1.31.1", "lightningcss-linux-x64-musl": "1.31.1", "lightningcss-win32-arm64-msvc": "1.31.1", "lightningcss-win32-x64-msvc": "1.31.1" } }, "sha512-l51N2r93WmGUye3WuFoN5k10zyvrVs0qfKBhyC5ogUQ6Ew6JUSswh78mbSO+IU3nTWsyOArqPCcShdQSadghBQ=="],
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
@@ -3150,12 +3401,18 @@
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" }, "bundled": true }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
"@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@tailwindcss/vite/@tailwindcss/node": ["@tailwindcss/node@4.1.11", "", { "dependencies": { "@ampproject/remapping": "^2.3.0", "enhanced-resolve": "^5.18.1", "jiti": "^2.4.2", "lightningcss": "1.30.1", "magic-string": "^0.30.17", "source-map-js": "^1.2.1", "tailwindcss": "4.1.11" } }, "sha512-yzhzuGRmv5QyU9qLNg4GTlYI6STedBWRE7NjxP45CsFYYq9taI0zJXZBMqIC/c8fViNLhmrbpSFS57EoxUmD6Q=="],
"@tailwindcss/vite/@tailwindcss/oxide": ["@tailwindcss/oxide@4.1.11", "", { "dependencies": { "detect-libc": "^2.0.4", "tar": "^7.4.3" }, "optionalDependencies": { "@tailwindcss/oxide-android-arm64": "4.1.11", "@tailwindcss/oxide-darwin-arm64": "4.1.11", "@tailwindcss/oxide-darwin-x64": "4.1.11", "@tailwindcss/oxide-freebsd-x64": "4.1.11", "@tailwindcss/oxide-linux-arm-gnueabihf": "4.1.11", "@tailwindcss/oxide-linux-arm64-gnu": "4.1.11", "@tailwindcss/oxide-linux-arm64-musl": "4.1.11", "@tailwindcss/oxide-linux-x64-gnu": "4.1.11", "@tailwindcss/oxide-linux-x64-musl": "4.1.11", "@tailwindcss/oxide-wasm32-wasi": "4.1.11", "@tailwindcss/oxide-win32-arm64-msvc": "4.1.11", "@tailwindcss/oxide-win32-x64-msvc": "4.1.11" } }, "sha512-Q69XzrtAhuyfHo+5/HMgr1lAiPP/G40OMFAnws7xcFEYqcypZmdW8eGXaOUIeOl1dzPJBPENXgbjsOyhg2nkrg=="],
"@tailwindcss/vite/tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
"@testing-library/dom/aria-query": ["aria-query@5.3.0", "", { "dependencies": { "dequal": "^2.0.3" } }, "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A=="],
"@testing-library/dom/dom-accessibility-api": ["dom-accessibility-api@0.5.16", "", {}, "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg=="],
@@ -3214,6 +3471,8 @@
"glob/minimatch": ["minimatch@10.1.2", "", { "dependencies": { "@isaacs/brace-expansion": "^5.0.1" } }, "sha512-fu656aJ0n2kcXwsnwnv9g24tkU5uSmOlTjd6WyyaKm2Z+h1qmY6bAjrcaIxF/BslFqbZ8UBtbJi7KgQOZD2PTw=="],
"gray-matter/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
"istanbul-lib-report/supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"jszip/readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
@@ -3250,8 +3509,6 @@
"mocha/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"mocha/js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
"mocha/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
"mocha/supports-color": ["supports-color@8.1.1", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q=="],
@@ -3260,6 +3517,8 @@
"mocha/yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
"npm-run-path/path-key": ["path-key@4.0.0", "", {}, "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ=="],
"nypm/citty": ["citty@0.2.0", "", {}, "sha512-8csy5IBFI2ex2hTVpaHN2j+LNE199AgiI7y4dMintrr8i0lQiFn+0AWMZrWdHKIgMOer65f8IThysYhoReqjWA=="],
@@ -3294,6 +3553,8 @@
"playwright/fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
"posthog-js/@opentelemetry/resources": ["@opentelemetry/resources@2.5.1", "", { "dependencies": { "@opentelemetry/core": "2.5.1", "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.3.0 <1.10.0" } }, "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ=="],
"pretty-format/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"pretty-format/ansi-styles": ["ansi-styles@5.2.0", "", {}, "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="],
@@ -3310,6 +3571,8 @@
"rimraf/glob": ["glob@10.5.0", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^3.1.2", "minimatch": "^9.0.4", "minipass": "^7.1.2", "package-json-from-dist": "^1.0.0", "path-scurry": "^1.11.1" }, "bin": { "glob": "dist/esm/bin.mjs" } }, "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg=="],
"sharp/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"shiki/@shikijs/core": ["@shikijs/core@3.20.0", "", { "dependencies": { "@shikijs/types": "3.20.0", "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4", "hast-util-to-html": "^9.0.5" } }, "sha512-f2ED7HYV4JEk827mtMDwe/yQ25pRiXZmtHjWF8uzZKuKiEsJR7Ce1nuQ+HhV9FzDcbIo4ObBCD9GPTzNuy9S1g=="],
"shiki/@shikijs/types": ["@shikijs/types@3.20.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-lhYAATn10nkZcBQ0BlzSbJA3wcmL5MXUUF8d2Zzon6saZDlToKaiRX60n2+ZaHJCmXEcZRWNzn+k9vplr8Jhsw=="],
@@ -3322,6 +3585,8 @@
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"strip-literal/js-tokens": ["js-tokens@9.0.1", "", {}, "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ=="],
"tar/yallist": ["yallist@5.0.0", "", {}, "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw=="],
"terser/commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
@@ -3336,6 +3601,8 @@
"url/punycode": ["punycode@1.3.2", "", {}, "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw=="],
"vitest/why-is-node-running": ["why-is-node-running@2.3.0", "", { "dependencies": { "siginfo": "^2.0.0", "stackback": "0.0.2" }, "bin": { "why-is-node-running": "cli.js" } }, "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w=="],
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.3", "", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -3360,12 +3627,8 @@
"@eslint/eslintrc/ajv/json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"@eslint/eslintrc/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"@eslint/eslintrc/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
"@hey-api/json-schema-ref-parser/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"@hey-api/openapi-ts/open/wsl-utils": ["wsl-utils@0.3.1", "", { "dependencies": { "is-wsl": "^3.1.0", "powershell-utils": "^0.1.0" } }, "sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg=="],
"@isaacs/cliui/string-width/emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
@@ -3430,6 +3693,24 @@
"@opencode-ai/ui/vite/esbuild": ["esbuild@0.25.12", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.12", "@esbuild/android-arm": "0.25.12", "@esbuild/android-arm64": "0.25.12", "@esbuild/android-x64": "0.25.12", "@esbuild/darwin-arm64": "0.25.12", "@esbuild/darwin-x64": "0.25.12", "@esbuild/freebsd-arm64": "0.25.12", "@esbuild/freebsd-x64": "0.25.12", "@esbuild/linux-arm": "0.25.12", "@esbuild/linux-arm64": "0.25.12", "@esbuild/linux-ia32": "0.25.12", "@esbuild/linux-loong64": "0.25.12", "@esbuild/linux-mips64el": "0.25.12", "@esbuild/linux-ppc64": "0.25.12", "@esbuild/linux-riscv64": "0.25.12", "@esbuild/linux-s390x": "0.25.12", "@esbuild/linux-x64": "0.25.12", "@esbuild/netbsd-arm64": "0.25.12", "@esbuild/netbsd-x64": "0.25.12", "@esbuild/openbsd-arm64": "0.25.12", "@esbuild/openbsd-x64": "0.25.12", "@esbuild/openharmony-arm64": "0.25.12", "@esbuild/sunos-x64": "0.25.12", "@esbuild/win32-arm64": "0.25.12", "@esbuild/win32-ia32": "0.25.12", "@esbuild/win32-x64": "0.25.12" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg=="],
"@opentelemetry/exporter-logs-otlp-http/@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/otlp-exporter-base/@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/otlp-transformer/@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/otlp-transformer/@opentelemetry/resources/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/otlp-transformer/@opentelemetry/sdk-trace-base/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/sdk-logs/@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/sdk-logs/@opentelemetry/resources/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/sdk-metrics/@opentelemetry/core/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentelemetry/sdk-metrics/@opentelemetry/resources/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"@opentui/solid/@babel/core/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@opentui/solid/solid-js/seroval": ["seroval@1.5.0", "", {}, "sha512-OE4cvmJ1uSPrKorFIH9/w/Qwuvi/IMcGbv5RKgcJ/zjA/IohDLU6SVaxFN9FwajbP7nsX0dQqMDes1whk3y+yw=="],
@@ -3440,7 +3721,55 @@
"@pierre/diffs/@shikijs/transformers/@shikijs/types": ["@shikijs/types@3.19.0", "", { "dependencies": { "@shikijs/vscode-textmate": "^10.0.2", "@types/hast": "^3.0.4" } }, "sha512-Z2hdeEQlzuntf/BZpFG8a+Fsw9UVXdML7w0o3TgSXV3yNESGon+bs9ITkQb3Ki7zxoXOOu5oJWqZ2uto06V9iQ=="],
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@storybook/addon-docs/react-dom/scheduler": ["scheduler@0.23.2", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ=="],
"@tailwindcss/node/lightningcss/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"@tailwindcss/node/lightningcss/lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.31.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-02uTEqf3vIfNMq3h/z2cJfcOXnQ0GRwQrkmPafhueLb2h7mqEidiCzkE4gBMEH65abHRiQvhdcQ+aP0D0g67sg=="],
"@tailwindcss/node/lightningcss/lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.31.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-1ObhyoCY+tGxtsz1lSx5NXCj3nirk0Y0kB/g8B8DT+sSx4G9djitg9ejFnjb3gJNWo7qXH4DIy2SUHvpoFwfTA=="],
"@tailwindcss/node/lightningcss/lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.31.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-1RINmQKAItO6ISxYgPwszQE1BrsVU5aB45ho6O42mu96UiZBxEXsuQ7cJW4zs4CEodPUioj/QrXW1r9pLUM74A=="],
"@tailwindcss/node/lightningcss/lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.31.1", "", { "os": "linux", "cpu": "arm" }, "sha512-OOCm2//MZJ87CdDK62rZIu+aw9gBv4azMJuA8/KB74wmfS3lnC4yoPHm0uXZ/dvNNHmnZnB8XLAZzObeG0nS1g=="],
"@tailwindcss/node/lightningcss/lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-WKyLWztD71rTnou4xAD5kQT+982wvca7E6QoLpoawZ1gP9JM0GJj4Tp5jMUh9B3AitHbRZ2/H3W5xQmdEOUlLg=="],
"@tailwindcss/node/lightningcss/lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.31.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-mVZ7Pg2zIbe3XlNbZJdjs86YViQFoJSpc41CbVmKBPiGmC4YrfeOyz65ms2qpAobVd7WQsbW4PdsSJEMymyIMg=="],
"@tailwindcss/node/lightningcss/lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-xGlFWRMl+0KvUhgySdIaReQdB4FNudfUTARn7q0hh/V67PVGCs3ADFjw+6++kG1RNd0zdGRlEKa+T13/tQjPMA=="],
"@tailwindcss/node/lightningcss/lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.31.1", "", { "os": "linux", "cpu": "x64" }, "sha512-eowF8PrKHw9LpoZii5tdZwnBcYDxRw2rRCyvAXLi34iyeYfqCQNA9rmUM0ce62NlPhCvof1+9ivRaTY6pSKDaA=="],
"@tailwindcss/node/lightningcss/lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.31.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-aJReEbSEQzx1uBlQizAOBSjcmr9dCdL3XuC/6HLXAxmtErsj2ICo5yYggg1qOODQMtnjNQv2UHb9NpOuFtYe4w=="],
"@tailwindcss/node/lightningcss/lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.31.1", "", { "os": "win32", "cpu": "x64" }, "sha512-I9aiFrbd7oYHwlnQDqr1Roz+fTz61oDDJX7n9tYF9FJymH1cIN1DtKw3iYt6b8WZgEjoNwVSncwF4wx/ZedMhw=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-android-arm64": ["@tailwindcss/oxide-android-arm64@4.1.11", "", { "os": "android", "cpu": "arm64" }, "sha512-3IfFuATVRUMZZprEIx9OGDjG3Ou3jG4xQzNTvjDoKmU9JdmoCohQJ83MYd0GPnQIu89YoJqvMM0G3uqLRFtetg=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-darwin-arm64": ["@tailwindcss/oxide-darwin-arm64@4.1.11", "", { "os": "darwin", "cpu": "arm64" }, "sha512-ESgStEOEsyg8J5YcMb1xl8WFOXfeBmrhAwGsFxxB2CxY9evy63+AtpbDLAyRkJnxLy2WsD1qF13E97uQyP1lfQ=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-darwin-x64": ["@tailwindcss/oxide-darwin-x64@4.1.11", "", { "os": "darwin", "cpu": "x64" }, "sha512-EgnK8kRchgmgzG6jE10UQNaH9Mwi2n+yw1jWmof9Vyg2lpKNX2ioe7CJdf9M5f8V9uaQxInenZkOxnTVL3fhAw=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-freebsd-x64": ["@tailwindcss/oxide-freebsd-x64@4.1.11", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xdqKtbpHs7pQhIKmqVpxStnY1skuNh4CtbcyOHeX1YBE0hArj2romsFGb6yUmzkq/6M24nkxDqU8GYrKrz+UcA=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm-gnueabihf": ["@tailwindcss/oxide-linux-arm-gnueabihf@4.1.11", "", { "os": "linux", "cpu": "arm" }, "sha512-ryHQK2eyDYYMwB5wZL46uoxz2zzDZsFBwfjssgB7pzytAeCCa6glsiJGjhTEddq/4OsIjsLNMAiMlHNYnkEEeg=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm64-gnu": ["@tailwindcss/oxide-linux-arm64-gnu@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-mYwqheq4BXF83j/w75ewkPJmPZIqqP1nhoghS9D57CLjsh3Nfq0m4ftTotRYtGnZd3eCztgbSPJ9QhfC91gDZQ=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-arm64-musl": ["@tailwindcss/oxide-linux-arm64-musl@4.1.11", "", { "os": "linux", "cpu": "arm64" }, "sha512-m/NVRFNGlEHJrNVk3O6I9ggVuNjXHIPoD6bqay/pubtYC9QIdAMpS+cswZQPBLvVvEF6GtSNONbDkZrjWZXYNQ=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-x64-gnu": ["@tailwindcss/oxide-linux-x64-gnu@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-YW6sblI7xukSD2TdbbaeQVDysIm/UPJtObHJHKxDEcW2exAtY47j52f8jZXkqE1krdnkhCMGqP3dbniu1Te2Fg=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-linux-x64-musl": ["@tailwindcss/oxide-linux-x64-musl@4.1.11", "", { "os": "linux", "cpu": "x64" }, "sha512-e3C/RRhGunWYNC3aSF7exsQkdXzQ/M+aYuZHKnw4U7KQwTJotnWsGOIVih0s2qQzmEzOFIJ3+xt7iq67K/p56Q=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi": ["@tailwindcss/oxide-wasm32-wasi@4.1.11", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@emnapi/wasi-threads": "^1.0.2", "@napi-rs/wasm-runtime": "^0.2.11", "@tybys/wasm-util": "^0.9.0", "tslib": "^2.8.0" }, "cpu": "none" }, "sha512-Xo1+/GU0JEN/C/dvcammKHzeM6NqKovG+6921MR6oadee5XPBaKOumrJCXvopJ/Qb5TH7LX/UAywbqrP4lax0g=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-win32-arm64-msvc": ["@tailwindcss/oxide-win32-arm64-msvc@4.1.11", "", { "os": "win32", "cpu": "arm64" }, "sha512-UgKYx5PwEKrac3GPNPf6HVMNhUIGuUh4wlDFR2jYYdkX6pL/rn73zTq/4pzUm8fOjAn5L8zDeHp9iXmUGOXZ+w=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-win32-x64-msvc": ["@tailwindcss/oxide-win32-x64-msvc@4.1.11", "", { "os": "win32", "cpu": "x64" }, "sha512-YfHoggn1j0LK7wR82TOucWc5LDCguHnoS879idHekmmiR7g9HUtMw9MI0NHatS28u/Xlkfi9w5RJWgz2Dl+5Qg=="],
"@tailwindcss/vite/@tailwindcss/oxide/detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
"@vscode/test-cli/chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@@ -3490,6 +3819,8 @@
"form-data/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"gray-matter/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"jszip/readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"jszip/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
@@ -3508,8 +3839,6 @@
"mocha/glob/path-scurry": ["path-scurry@1.11.1", "", { "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA=="],
"mocha/js-yaml/argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"mocha/yargs/cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"mocha/yargs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
@@ -3526,6 +3855,10 @@
"pkg-up/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="],
"posthog-js/@opentelemetry/resources/@opentelemetry/core": ["@opentelemetry/core@2.5.1", "", { "dependencies": { "@opentelemetry/semantic-conventions": "^1.29.0" }, "peerDependencies": { "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, "sha512-Dwlc+3HAZqpgTYq0MUyZABjFkcrKTePwuiFVLjahGD8cx3enqihmpAmdgNFO1R4m/sIe5afjJrA25Prqy4NXlA=="],
"posthog-js/@opentelemetry/resources/@opentelemetry/semantic-conventions": ["@opentelemetry/semantic-conventions@1.39.0", "", {}, "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg=="],
"qrcode/yargs/cliui": ["cliui@6.0.0", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.0", "wrap-ansi": "^6.2.0" } }, "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ=="],
"qrcode/yargs/find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
@@ -3732,6 +4065,18 @@
"@opencode-ai/ui/vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.25.12", "", { "os": "win32", "cpu": "x64" }, "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.8.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" }, "bundled": true }, "sha512-AvT9QFpxK0Zd8J0jopedNm+w/2fIzvtPKPjqyw9jwvBaReTTqPBk9Hixaz7KbjimP+QNz605/XnjFcDAL2pqBg=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.8.1", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-mehfKSMWjjNol8659Z8KxEMrdSJDDot5SXMq00dM8BN4o+CLNXQ0xH2V7EchNHV4RmbZLmmPdEaXZc5H2FXmDg=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.1.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@0.2.12", "", { "dependencies": { "@emnapi/core": "^1.4.3", "@emnapi/runtime": "^1.4.3", "@tybys/wasm-util": "^0.10.0" }, "bundled": true }, "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@tybys/wasm-util": ["@tybys/wasm-util@0.9.0", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@vscode/test-cli/chokidar/readdirp/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"@vscode/test-cli/glob/path-scurry/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
@@ -3790,6 +4135,8 @@
"@joshwooding/vite-plugin-react-docgen-typescript/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@4.0.3", "", {}, "sha512-1pHv8LX9CpKut1Zp4EXey7Z8OfH11ONNH6Dhi2WDUt31VVZFXZzKwXcysBgqSumFCmR+0dqjMK5v5JiFHzi0+g=="],
"@tailwindcss/vite/@tailwindcss/oxide/@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime/@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
"@vscode/test-cli/yargs/cliui/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"@vscode/test-cli/yargs/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+6
View File
@@ -0,0 +1,6 @@
NEXT_PUBLIC_ALGOLIA_APP_ID=ABC123
NEXT_PUBLIC_ALGOLIA_API_KEY=zyz6789
NEXT_PUBLIC_ALGOLIA_INDEX_NAME="Kilo Code Docs"
NEXT_PUBLIC_ALGOLIA_ASSISTANT_ID=foo-bar
NEXT_PUBLIC_POSTHOG_KEY=phc_QWERTY
NEXT_PUBLIC_POSTHOG_HOST=https://us.i.posthog.com
+3
View File
@@ -0,0 +1,3 @@
# Use bd merge for beads JSONL files
.beads/issues.jsonl merge=beads
+11
View File
@@ -0,0 +1,11 @@
node_modules/
.DS_Store
.next/
.vercel
package-lock.json
yarn.lock
screenshots/
.beads/
.env
next-env.d.ts
tsconfig.tsbuildinfo
+11
View File
@@ -0,0 +1,11 @@
{
"mcpServers": {
"context7": {
"command": "npx",
"args": ["-y", "@upstash/context7-mcp"],
"env": { "DEFAULT_MINIMUM_TOKENS": "" },
"alwaysAllow": ["resolve-library-id", "query-docs"],
"disabled": true
}
}
}
+94
View File
@@ -0,0 +1,94 @@
## Project Overview
This is the Kilo Code documentation site. Kilo Code is the leading open source agentic engineering platform.
## Dev Server
The dev server is run with `bun dev` and runs on `http://localhost:3002`. Typically the user will be running it themselves, so always check if it is running FIRST before deciding to run it yourself to test something.
## Branch Naming Convention
When making changes _only_ to the documentation, create branches with the `docs/` prefix:
```bash
git checkout -b docs/description-of-change
```
This convention helps identify documentation-only PRs and keeps them organized.
## Markdoc Custom Tags
This project uses [Markdoc](https://markdoc.dev/) for rendering markdown with custom components. Custom tags allow you to embed React components directly in markdown files.
### Images
Use the Markdoc image tag format:
```markdown
{% image src="/docs/img/kilo-provider/connected-accounts.png" alt="Connect account screen" width="800" caption="Connect account screen" /%}
```
Note that this site is served under kilo.ai/docs so the `/docs` prefix **must** be present in every image path.
Image attributes:
| Attribute | Type | Required | Description |
| --------- | ------ | -------- | ------------------------------------------- |
| `src` | String | Yes | The image source URL |
| `alt` | String | Yes | Alternative text for the image |
| `width` | String | No | Width of the image (e.g., '500px', '80%') |
| `height` | String | No | Height of the image (e.g., '300px', 'auto') |
| `caption` | String | No | Caption displayed below the image |
### Callouts
Use the Markdoc callout tag format:
```markdown
{% callout type="info" %}
You can report any bugs or feedback by chatting with us in our [Discord server](https://discord.gg/ovhcloud), in the AI Endpoints channel.
{% /callout %}
```
Callout attributes:
| Attribute | Type | Default | Description |
| ----------- | ------- | ------- | ------------------------------------------------- |
| `title` | String | - | Optional custom title for the callout |
| `type` | String | "note" | One of: generic, note, tip, info, warning, danger |
| `collapsed` | Boolean | false | When true, the callout starts collapsed |
### Codicons
Use the Markdoc codicon tag format:
```markdown
{% codicon name="gear" /%}
```
## Documentation Guidelines
### Adding New Pages
1. Create your page in the appropriate directory under `pages/`
2. **Always update navigation**: Add the page to the corresponding navigation file in `lib/nav/`
- Each section has its own nav file (e.g., `getting-started.ts`, `code-with-ai.ts`, `ai-providers.ts`)
- Navigation structure is exported from `lib/nav/index.ts`
- See `lib/types.ts` for the `NavSection` and `NavLink` interfaces
### Removing or Moving Pages
**Never remove a page without adding a redirect.** This prevents broken links from search engines, external references, and user bookmarks.
1. Add a redirect entry to `previous-docs-redirects.js`
2. Redirect format:
```javascript
{
source: "/docs/old-path",
destination: "/docs/new-path",
basePath: false,
permanent: true,
}
```
3. Update the navigation file to remove or update the link
4. Redirects are loaded in `next.config.js`
+55
View File
@@ -0,0 +1,55 @@
# Full Next.js example
This is a full-featured boilerplate for a creating a documentation website using Markdoc and Next.js.
<img width="2032" alt="image" src="https://user-images.githubusercontent.com/62121649/174916143-16f18270-0463-402c-8b48-33c627ea7a7e.png">
## Setup
First, clone this repo and install the dependencies required:
```bash
npm install
# or
yarn install
```
Then, run the development server:
```bash
npm run dev
# or
yarn dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `index.md`. The page auto-updates as you edit the file.
## Deploy
The quickest way to deploy your own version of this boilerplate is by deploying it with [Vercel](https://vercel.com) or [Netlify](https://www.netlify.com/) by clicking one of the buttons below.
### Deploy with Vercel
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/markdoc/next.js-starter)
### Deploy to Netlify
[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/markdoc/next.js-starter)
## Contributing
When making documentation _only_ changes, use branch names prefixed with `docs/`:
```bash
git checkout -b docs/your-change-description
```
Examples:
- `docs/add-mcp-tutorial`
- `docs/fix-installation-steps`
- `docs/update-api-reference`
For full contribution guidelines, see the [Contributing Guide](https://kilo.ai/docs/contributing).
@@ -0,0 +1,137 @@
/**
* Tests for redirect loop detection in previous-docs-redirects.js
*
* This test suite verifies that the redirect configuration has no loops:
* 1. Direct loops: A path redirecting to itself (source === destination)
* 2. Indirect loops: A chain of redirects leading back to a starting point (A → B → C → A)
*/
import { expect, describe, it } from "vitest"
import redirects from "../previous-docs-redirects.js"
interface Redirect {
source: string
destination: string
basePath?: boolean
permanent?: boolean
}
describe("previous-docs-redirects", () => {
describe("direct loop detection", () => {
it("should not have any redirects where source equals destination", () => {
const directLoops: Redirect[] = []
for (const redirect of redirects as Redirect[]) {
if (redirect.source === redirect.destination) {
directLoops.push(redirect)
}
}
if (directLoops.length > 0) {
const loopDetails = directLoops.map((r) => ` - "${r.source}" redirects to itself`).join("\n")
expect.fail(`Found ${directLoops.length} direct redirect loop(s):\n${loopDetails}`)
}
})
})
describe("indirect loop detection", () => {
it("should not have any redirect chains that form a cycle", () => {
// Build a map of source -> destination for quick lookup
// Note: We only consider exact path matches, not wildcard patterns like :path*
// Also skip direct loops (source === destination) as they're caught by the direct loop test
const redirectMap = new Map<string, string>()
for (const redirect of redirects as Redirect[]) {
// Skip wildcard redirects as they don't form exact chains
// Skip direct loops as they're caught by the direct loop test
if (
!redirect.source.includes(":") &&
!redirect.source.includes("*") &&
redirect.source !== redirect.destination
) {
redirectMap.set(redirect.source, redirect.destination)
}
}
const cycles: string[][] = []
/**
* Detects if following redirects from a starting path leads back to any path in the chain.
* Uses a visited set to track the current chain and detect cycles.
*/
function detectCycle(startPath: string): string[] | null {
const visited = new Set<string>()
const chain: string[] = [startPath]
let currentPath = startPath
while (redirectMap.has(currentPath)) {
const nextPath = redirectMap.get(currentPath)!
if (visited.has(nextPath)) {
// Found a cycle - return the chain from the cycle start
const cycleStartIndex = chain.indexOf(nextPath)
if (cycleStartIndex !== -1) {
return [...chain.slice(cycleStartIndex), nextPath]
}
return null
}
visited.add(currentPath)
chain.push(nextPath)
currentPath = nextPath
}
return null
}
// Check each redirect source for potential cycles
for (const source of redirectMap.keys()) {
const cycle = detectCycle(source)
if (cycle) {
// Avoid duplicate cycle reports by checking if we've already found this cycle
const cycleKey = [...cycle].sort().join(" -> ")
const isDuplicate = cycles.some(
(existingCycle) => [...existingCycle].sort().join(" -> ") === cycleKey,
)
if (!isDuplicate) {
cycles.push(cycle)
}
}
}
if (cycles.length > 0) {
const cycleDetails = cycles.map((cycle) => ` - ${cycle.join(" → ")}`).join("\n")
expect.fail(`Found ${cycles.length} indirect redirect cycle(s):\n${cycleDetails}`)
}
})
})
describe("redirect structure validation", () => {
it("should have valid redirect objects with required properties", () => {
const invalidRedirects: { index: number; issues: string[] }[] = []
;(redirects as Redirect[]).forEach((redirect, index) => {
const issues: string[] = []
if (typeof redirect.source !== "string" || redirect.source.trim() === "") {
issues.push("missing or invalid 'source' property")
}
if (typeof redirect.destination !== "string" || redirect.destination.trim() === "") {
issues.push("missing or invalid 'destination' property")
}
if (issues.length > 0) {
invalidRedirects.push({ index, issues })
}
})
if (invalidRedirects.length > 0) {
const details = invalidRedirects
.map((r) => ` - Redirect at index ${r.index}: ${r.issues.join(", ")}`)
.join("\n")
expect.fail(`Found ${invalidRedirects.length} invalid redirect(s):\n${details}`)
}
})
})
})
+115
View File
@@ -0,0 +1,115 @@
import * as React from "react"
type CalloutType = "generic" | "note" | "tip" | "info" | "warning" | "danger"
interface CalloutProps {
type?: CalloutType
title?: string
collapsed?: boolean
children: React.ReactNode
}
const typeConfig: Record<
CalloutType,
{
icon: string | null
defaultTitle: string | null
borderColor: string
bgColor: string
titleColor: string
iconColor: string
}
> = {
generic: {
icon: null,
defaultTitle: null,
borderColor: "border-l-gray-300 dark:border-l-gray-600",
bgColor: "bg-gray-50 dark:bg-gray-800/50",
titleColor: "text-gray-700 dark:text-gray-300",
iconColor: "text-gray-400",
},
note: {
icon: "📝",
defaultTitle: "Note",
borderColor: "border-l-gray-500",
bgColor: "bg-gray-50 dark:bg-gray-800/50",
titleColor: "text-gray-700 dark:text-gray-300",
iconColor: "text-gray-500",
},
tip: {
icon: "💡",
defaultTitle: "Tip",
borderColor: "border-l-green-500",
bgColor: "bg-green-50 dark:bg-green-900/20",
titleColor: "text-green-700 dark:text-green-400",
iconColor: "text-green-500",
},
info: {
icon: "️",
defaultTitle: "Info",
borderColor: "border-l-blue-500",
bgColor: "bg-blue-50 dark:bg-blue-900/20",
titleColor: "text-blue-700 dark:text-blue-400",
iconColor: "text-blue-500",
},
warning: {
icon: "⚠️",
defaultTitle: "Warning",
borderColor: "border-l-yellow-500",
bgColor: "bg-yellow-50 dark:bg-yellow-900/20",
titleColor: "text-yellow-700 dark:text-yellow-400",
iconColor: "text-yellow-500",
},
danger: {
icon: "🚨",
defaultTitle: "Danger",
borderColor: "border-l-red-500",
bgColor: "bg-red-50 dark:bg-red-900/20",
titleColor: "text-red-700 dark:text-red-400",
iconColor: "text-red-500",
},
}
export function Callout({ type = "note", title, collapsed = false, children }: CalloutProps) {
const [isExpanded, setIsExpanded] = React.useState(!collapsed)
const config = typeConfig[type]
const displayTitle = title ?? config.defaultTitle
const showHeader = displayTitle || config.icon
// If collapsed prop is set, make the header clickable
if (collapsed) {
return (
<div className={`my-4 border-l-4 ${config.borderColor} ${config.bgColor} rounded-r-lg p-4`}>
{showHeader && (
<button
type="button"
onClick={() => setIsExpanded(!isExpanded)}
className={`flex items-center gap-2 font-semibold ${config.titleColor} w-full text-left cursor-pointer ${isExpanded ? "mb-2" : ""}`}
aria-expanded={isExpanded}>
<span
className={`transition-transform duration-200 ${isExpanded ? "rotate-90" : ""}`}
aria-hidden="true">
</span>
{config.icon && <span className={config.iconColor}>{config.icon}</span>}
{displayTitle && <span className="uppercase text-sm tracking-wide">{displayTitle}</span>}
</button>
)}
{isExpanded && <div className="text-gray-700 dark:text-gray-300 [&>p]:m-0">{children}</div>}
</div>
)
}
// Default non-collapsible behavior
return (
<div className={`my-4 border-l-4 ${config.borderColor} ${config.bgColor} rounded-r-lg p-4`}>
{showHeader && (
<div className={`flex items-center gap-2 font-semibold ${config.titleColor} mb-2`}>
{config.icon && <span className={config.iconColor}>{config.icon}</span>}
{displayTitle && <span className="uppercase text-sm tracking-wide">{displayTitle}</span>}
</div>
)}
<div className="text-gray-700 dark:text-gray-300 [&>p]:m-0">{children}</div>
</div>
)
}
+105
View File
@@ -0,0 +1,105 @@
import Prism from "prismjs"
import * as React from "react"
import { Codicon } from "./Codicon"
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 (ref.current) Prism.highlightElement(ref.current, false)
}, [children])
React.useEffect(() => {
return () => {
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
}
}, [])
const handleCopy = async () => {
const code = ref.current?.textContent || ""
try {
await navigator.clipboard.writeText(code)
setCopied(true)
if (timeoutRef.current) {
clearTimeout(timeoutRef.current)
}
timeoutRef.current = setTimeout(() => setCopied(false), 2000)
} catch (err) {
console.error("Failed to copy code:", err)
}
}
return (
<div className="code" aria-live="polite">
<button
type="button"
className="copy-button"
onClick={handleCopy}
aria-label="Copy code to clipboard"
title={copied ? "Copied!" : "Copy code"}>
{copied ? <Codicon name="check" /> : <Codicon name="copy" />}
</button>
<pre ref={ref} className={`language-${language}`}>
{children}
</pre>
<style jsx>
{`
.code {
position: relative;
}
.copy-button {
position: absolute;
top: 8px;
right: 8px;
padding: 6px 8px;
background: rgba(0, 0, 0, 0.05);
border: 1px solid rgba(0, 0, 0, 0.1);
border-radius: 4px;
color: rgba(0, 0, 0, 0.4);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.2s ease;
z-index: 10;
}
.copy-button:hover {
background: rgba(0, 0, 0, 0.1);
color: rgba(0, 0, 0, 0.6);
border-color: rgba(0, 0, 0, 0.2);
}
:global(.dark) .copy-button {
background: rgba(255, 255, 255, 0.05);
border-color: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.4);
}
:global(.dark) .copy-button:hover {
background: rgba(255, 255, 255, 0.1);
color: rgba(255, 255, 255, 0.7);
border-color: rgba(255, 255, 255, 0.2);
}
.copy-button:active {
transform: scale(0.95);
}
/* Override Prism styles */
.code :global(pre[class*="language-"]) {
text-shadow: none;
border-radius: 4px;
padding-right: 3.5rem;
}
`}
</style>
</div>
)
}
+22
View File
@@ -0,0 +1,22 @@
import React from "react"
import "@vscode/codicons/dist/codicon.css"
interface CodiconProps {
name: string
size?: string
className?: string
}
export function Codicon({ name, size = "1em", className = "" }: CodiconProps) {
return (
<i
className={`codicon codicon-${name} ${className}`.trim()}
style={{
fontSize: size,
verticalAlign: "middle",
display: "inline",
}}
aria-hidden="true"
/>
)
}
@@ -0,0 +1,159 @@
import React, { useState, useEffect } from "react"
import { useRouter } from "next/router"
interface CopyPageButtonProps {
className?: string
}
export function CopyPageButton({ className }: CopyPageButtonProps) {
const router = useRouter()
const [copied, setCopied] = useState(false)
const [error, setError] = useState(false)
const [isLoading, setIsLoading] = useState(false)
// Reset copied/error state after 3 seconds
useEffect(() => {
if (copied || error) {
const timer = setTimeout(() => {
setCopied(false)
setError(false)
}, 3000)
return () => clearTimeout(timer)
}
}, [copied, error])
const handleCopy = async () => {
if (copied || error || isLoading) return
setIsLoading(true)
try {
// Fetch the raw markdown file based on current route
// The route path maps to pages/<path>.md
const path = router.asPath.split("#")[0].split("?")[0] // Remove hash and query params
const mdPath = path === "/" ? "/index" : path
// Fetch the raw markdown content from the API route
const response = await fetch(`/docs/api/raw-markdown?path=${encodeURIComponent(mdPath)}`)
if (!response.ok) {
throw new Error("Failed to fetch markdown")
}
const markdown = await response.text()
await navigator.clipboard.writeText(markdown)
setCopied(true)
} catch (err) {
console.error("Failed to copy page:", err)
setError(true)
} finally {
setIsLoading(false)
}
}
return (
<>
<button
onClick={handleCopy}
disabled={copied || error || isLoading}
className={`copy-page-button ${copied ? "copied" : ""} ${error ? "errored" : ""} ${className || ""}`}
aria-label={copied ? "Copied" : error ? "Copy failed" : "Copy page markdown"}
title="Copy page as markdown for use with LLMs"
>
{copied ? (
<>
<CheckIcon />
<span>Copied</span>
</>
) : error ? (
<>
<span>Copy failed</span>
</>
) : (
<>
<CopyIcon />
<span>Copy page</span>
</>
)}
</button>
<style jsx>{`
.copy-page-button {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
font-weight: 500;
font-family: inherit;
color: var(--text-secondary);
background: var(--bg-secondary);
border: 1px solid var(--border-color);
border-radius: 0.5rem;
cursor: pointer;
transition: all 0.15s ease;
white-space: nowrap;
}
.copy-page-button:hover:not(:disabled) {
background: var(--bg-tertiary, var(--bg-secondary));
color: var(--text-brand);
border-color: var(--text-brand);
}
.copy-page-button:disabled {
cursor: default;
}
.copy-page-button.copied {
color: var(--success-color, #22c55e);
border-color: var(--success-color, #22c55e);
background: var(--success-bg, rgba(34, 197, 94, 0.1));
}
.copy-page-button.errored {
color: var(--error-color, #ef4444);
border-color: var(--error-color, #ef4444);
background: var(--error-bg, rgba(239, 68, 68, 0.1));
}
`}</style>
</>
)
}
// Copy icon (two overlapping rectangles)
function CopyIcon() {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
>
<rect x="5" y="5" width="9" height="9" rx="1.5" />
<path d="M2 10V3.5A1.5 1.5 0 0 1 3.5 2H10" />
</svg>
)
}
// Check icon for copied state
function CheckIcon() {
return (
<svg
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="M3 8.5L6.5 12L13 4" />
</svg>
)
}
+12
View File
@@ -0,0 +1,12 @@
import * as React from "react"
export function Heading({ id = "", level = 1, children, className }) {
return React.createElement(
`h${level}`,
{
id,
className: ["heading", className].filter(Boolean).join(" "),
},
children,
)
}
+49
View File
@@ -0,0 +1,49 @@
import React, { useEffect, useState } from "react"
interface IconProps {
src: string
srcDark?: string
alt?: string
size?: string
}
export function Icon({ src, srcDark, alt = "icon", size = "1.2em" }: IconProps) {
const [isDark, setIsDark] = useState(false)
useEffect(() => {
// Check initial dark mode state
const checkDarkMode = () => {
setIsDark(document.documentElement.classList.contains("dark"))
}
checkDarkMode()
// Watch for dark mode changes
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
if (mutation.attributeName === "class") {
checkDarkMode()
}
})
})
observer.observe(document.documentElement, { attributes: true })
return () => observer.disconnect()
}, [])
const imageSrc = isDark && srcDark ? srcDark : src
return (
<img
src={imageSrc}
alt={alt}
style={{
height: size,
width: "auto",
verticalAlign: "middle",
display: "inline",
}}
/>
)
}
+58
View File
@@ -0,0 +1,58 @@
import React from "react"
interface ImageProps {
src: string
alt: string
width?: string
height?: string
caption?: string
}
// Helper to add 'px' to numeric values that don't have units
function addPxIfNeeded(value: string): string {
// If the value is purely numeric, add 'px'
if (/^\d+(\.\d+)?$/.test(value)) {
return `${value}px`
}
return value
}
export function Image({ src, alt, width, height, caption }: ImageProps) {
const imgStyle: React.CSSProperties = {
maxWidth: "100%",
height: "auto",
}
if (width) imgStyle.width = addPxIfNeeded(width)
if (height) imgStyle.height = addPxIfNeeded(height)
const figureStyle: React.CSSProperties = {
margin: "1.5rem 0",
maxWidth: "100%",
overflow: "hidden",
}
// If width is specified, apply it to the figure to constrain caption width
if (width) {
figureStyle.width = addPxIfNeeded(width)
figureStyle.maxWidth = "100%"
}
return (
<figure style={figureStyle}>
<img src={src} alt={alt} style={imgStyle} />
{caption && (
<figcaption
style={{
fontStyle: "italic",
textAlign: "center",
marginTop: "0.5rem",
color: "var(--gray-600, #6b7280)",
width: "100%",
}}>
{caption}
</figcaption>
)}
</figure>
)
}
@@ -0,0 +1,10 @@
import React from "react"
import { Icon } from "./Icon"
interface KiloCodeIconProps {
size?: string
}
export function KiloCodeIcon({ size = "1.2em" }: KiloCodeIconProps) {
return <Icon src="/docs/img/kilo-v1.svg" srcDark="/docs/img/kilo-v1-white.svg" alt="Kilo Code Icon" size={size} />
}
+648
View File
@@ -0,0 +1,648 @@
import React, { useState, useEffect } from "react"
import { useRouter } from "next/router"
import Link from "next/link"
import { SectionNav } from "../lib/types"
import { Nav } from "../lib/nav"
// Define navigation items for each major section
const sectionNavItems: SectionNav = {
"getting-started": Nav.GettingStartedNav,
"code-with-ai": Nav.CodeWithAiNav,
customize: Nav.CustomizeNav,
collaborate: Nav.CollaborateNav,
"automate/tools": Nav.ToolsNav,
automate: Nav.AutomateNav,
"deploy-secure": Nav.DeploySecureNav,
contributing: Nav.ContributingNav,
"ai-providers": Nav.AiProvidersNav,
gateway: Nav.GatewayNav,
}
// Main nav items with their section keys
const mainNavItems = [
{ label: "Home", href: "/", sectionKey: null },
{ label: "Get Started", href: "/getting-started", sectionKey: "getting-started" },
{ label: "Code with AI", href: "/code-with-ai", sectionKey: "code-with-ai" },
{ label: "Customize", href: "/customize", sectionKey: "customize" },
{ label: "Collaborate", href: "/collaborate", sectionKey: "collaborate" },
{ label: "Automate", href: "/automate", sectionKey: "automate" },
{ label: "Deploy & Secure", href: "/deploy-secure", sectionKey: "deploy-secure" },
{ label: "AI Gateway", href: "/gateway", sectionKey: "gateway" },
{ label: "Contributing", href: "/contributing", sectionKey: "contributing" },
]
function getCurrentSection(pathname: string): string | null {
const sectionKeys = Object.keys(sectionNavItems)
for (const section of sectionKeys) {
if (pathname.startsWith(`/${section}`)) {
return section
}
}
return null
}
function getSectionLabel(sectionKey: string): string {
const item = mainNavItems.find((nav) => nav.sectionKey === sectionKey)
return item?.label || sectionKey
}
// Chevron icons as components
const ChevronRight = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" style={{ flexShrink: 0 }}>
<path d="M6 4L10 8L6 12" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
)
const ChevronDown = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" style={{ flexShrink: 0 }}>
<path d="M4 6L8 10L12 6" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
</svg>
)
const ChevronLeft = () => (
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" style={{ flexShrink: 0 }}>
<path
d="M10 4L6 8L10 12"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
interface SideNavProps {
isMobileOpen?: boolean
onMobileClose?: () => void
}
export function SideNav({ isMobileOpen = false, onMobileClose }: SideNavProps) {
const router = useRouter()
const currentSection = getCurrentSection(router.pathname)
// Track which view is shown: 'main' or 'section'
const [activeView, setActiveView] = useState<"main" | "section">(currentSection ? "section" : "main")
// Track which section is being viewed (for animation purposes)
const [viewedSection, setViewedSection] = useState<string | null>(currentSection)
// Track which nav items are expanded (for nested navigation)
const [expandedItems, setExpandedItems] = useState<Set<string>>(new Set())
// Update view when route changes
useEffect(() => {
const newSection = getCurrentSection(router.pathname)
if (newSection) {
setViewedSection(newSection)
setActiveView("section")
} else {
setActiveView("main")
}
}, [router.pathname])
// Auto-expand parent items when their child is active or when the parent itself is active
useEffect(() => {
const sectionItems = viewedSection ? sectionNavItems[viewedSection] || [] : []
const newExpandedItems = new Set<string>()
sectionItems.forEach((group) => {
group.links.forEach((link) => {
if (link.subLinks) {
const hasActiveChild = link.subLinks.some((subLink) => router.pathname === subLink.href)
const isParentActive = router.pathname === link.href
if (hasActiveChild || isParentActive) {
newExpandedItems.add(link.href)
}
}
})
})
setExpandedItems(newExpandedItems)
}, [router.pathname, viewedSection])
const handleLinkClick = () => {
if (onMobileClose) {
onMobileClose()
}
}
const handleSectionClick = (sectionKey: string | null) => {
if (sectionKey) {
setViewedSection(sectionKey)
setActiveView("section")
}
}
const handleBackClick = () => {
setActiveView("main")
}
const toggleExpanded = (href: string) => {
setExpandedItems((prev) => {
const newSet = new Set(prev)
if (newSet.has(href)) {
newSet.delete(href)
} else {
newSet.add(href)
}
return newSet
})
}
const sectionItems = viewedSection ? sectionNavItems[viewedSection] || [] : []
const sectionLabel = viewedSection ? getSectionLabel(viewedSection) : ""
// Main navigation panel
const mainNavPanel = (
<div className="nav-panel main-panel">
{mainNavItems.map((item) => {
const isActive = item.sectionKey ? router.pathname.startsWith(item.href) : router.pathname === item.href
const hasSubItems = item.sectionKey && sectionNavItems[item.sectionKey]
if (hasSubItems) {
return (
<button
type="button"
key={item.href}
onClick={() => handleSectionClick(item.sectionKey)}
className={`nav-item nav-item-button ${isActive ? "active" : ""}`}>
<span>{item.label}</span>
<span className="nav-arrow">
<ChevronRight />
</span>
</button>
)
}
return (
<Link
key={item.href}
href={item.href}
onClick={handleLinkClick}
className={`nav-item ${isActive ? "active" : ""}`}>
<span>{item.label}</span>
</Link>
)
})}
<style jsx>{`
.nav-panel {
width: 50%;
height: 100%;
overflow-y: auto;
padding: 1rem;
flex-shrink: 0;
}
.nav-item {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 0.75rem 1rem;
font-size: 0.9375rem;
font-weight: 500;
text-decoration: none;
color: var(--text-color);
border-radius: 0.5rem;
transition:
background-color 0.15s ease,
color 0.15s ease;
cursor: pointer;
}
.nav-item-button {
background: none;
border: none;
text-align: left;
font-family: inherit;
}
.nav-item:hover {
background-color: var(--bg-secondary);
}
.nav-item.active {
color: var(--accent-color);
}
.nav-arrow {
color: var(--text-secondary);
opacity: 0.6;
transition: opacity 0.15s ease;
display: flex;
align-items: center;
}
.nav-item:hover .nav-arrow {
opacity: 1;
}
`}</style>
</div>
)
// Section navigation panel
const sectionNavPanel = (
<div className="nav-panel section-panel">
<button type="button" className="back-button mobile-only" onClick={handleBackClick}>
<span className="back-arrow">
<ChevronLeft />
</span>
<span>{sectionLabel}</span>
</button>
<div className="section-content">
{sectionItems.map((group) => (
<div key={group.title} className="nav-group">
<span className="nav-group-title">{group.title}</span>
<ul className="nav-links">
{group.links.map((link) => {
const hasSubLinks = link.subLinks && link.subLinks.length > 0
const isExpanded = expandedItems.has(link.href)
const hasActiveChild = link.subLinks?.some(
(subLink) => router.pathname === subLink.href,
)
// Parent should only be active if it's the current page AND it has no active children
const active = router.pathname === link.href && !hasActiveChild
return (
<li
key={link.href}
className={`${active ? "active" : ""} ${hasSubLinks ? "has-children" : ""}`}>
{hasSubLinks ? (
<>
<div className="nav-item-with-toggle">
<Link href={link.href} onClick={handleLinkClick}>
{link.children}
</Link>
<button
type="button"
className="toggle-button"
onClick={(e) => {
e.preventDefault()
toggleExpanded(link.href)
}}
aria-label={isExpanded ? "Collapse" : "Expand"}>
{isExpanded ? <ChevronDown /> : <ChevronRight />}
</button>
</div>
{isExpanded && (
<ul className="sub-links">
{link.subLinks.map((subLink) => {
// Only mark sublink as active if it's an exact match
const subActive = router.pathname === subLink.href
return (
<li
key={subLink.href}
className={subActive ? "active" : ""}>
<Link href={subLink.href} onClick={handleLinkClick}>
{subLink.children}
</Link>
</li>
)
})}
</ul>
)}
</>
) : (
<Link href={link.href} onClick={handleLinkClick}>
{link.children}
</Link>
)}
</li>
)
})}
</ul>
</div>
))}
</div>
<style jsx>{`
.nav-panel {
width: 50%;
height: 100%;
overflow-y: auto;
padding: 1rem;
flex-shrink: 0;
}
.back-button {
display: none;
align-items: center;
gap: 0.5rem;
width: 100%;
padding: 0.75rem 1rem;
font-size: 0.9375rem;
font-weight: 600;
color: var(--text-color);
background: none;
border: none;
border-radius: 0.5rem;
cursor: pointer;
transition: background-color 0.15s ease;
font-family: inherit;
margin-bottom: 0.5rem;
}
@media (max-width: 768px) {
.back-button.mobile-only {
display: flex;
}
}
.back-button:hover {
background-color: var(--bg-secondary);
}
.back-arrow {
color: var(--text-secondary);
display: flex;
align-items: center;
}
.section-content {
padding-left: 0.25rem;
}
.nav-group {
margin-bottom: 1.25rem;
}
.nav-group-title {
display: block;
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 0.5rem 0.75rem;
color: var(--text-secondary);
}
.nav-links {
padding: 0;
margin: 0;
}
.nav-links li {
list-style: none;
margin: 0;
}
.nav-links li :global(a) {
display: block;
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
text-decoration: none;
color: var(--text-secondary);
border-radius: 0.375rem;
transition:
background-color 0.15s ease,
color 0.15s ease;
}
.nav-links li :global(a:hover) {
background-color: var(--bg-secondary);
color: var(--text-color);
}
.nav-links li.active > :global(a),
.nav-links li.active > :global(.nav-item-with-toggle) > :global(a) {
background-color: var(--bg-secondary);
color: var(--accent-color);
font-weight: 500;
}
/* Nested navigation styles */
.nav-links li.has-children {
margin: 0;
}
.nav-links :global(.nav-item-with-toggle) {
display: flex;
align-items: center;
justify-content: space-between;
gap: 0.25rem;
}
.nav-links :global(.nav-item-with-toggle a) {
flex: 1;
padding-right: 0.25rem;
}
.nav-links :global(.toggle-button) {
display: flex;
align-items: center;
justify-content: center;
padding: 0.375rem;
background: none;
border: none;
color: var(--text-secondary);
cursor: pointer;
border-radius: 0.25rem;
transition:
background-color 0.15s ease,
color 0.15s ease;
flex-shrink: 0;
}
.nav-links :global(.toggle-button:hover) {
background-color: var(--bg-secondary);
color: var(--text-color);
}
.nav-links :global(.sub-links) {
padding: 0;
margin: 0.25rem 0 0.5rem 0;
border-left: 2px solid var(--accent-color);
margin-left: 0.75rem;
}
.nav-links :global(.sub-links li) {
list-style: none;
margin: 0;
}
.nav-links :global(.sub-links a) {
display: block;
padding: 0.375rem 0.75rem;
padding-left: 1rem;
font-size: 0.8125rem;
text-decoration: none;
color: var(--text-secondary);
border-radius: 0 0.375rem 0.375rem 0;
transition:
background-color 0.15s ease,
color 0.15s ease;
}
.nav-links :global(.sub-links a:hover) {
background-color: var(--bg-secondary);
color: var(--text-color);
}
.nav-links :global(.sub-links li.active a) {
background-color: var(--bg-secondary);
color: var(--accent-color);
font-weight: 500;
}
`}</style>
</div>
)
const navContent = (
<div className={`sliding-nav ${activeView === "section" ? "show-section" : "show-main"}`}>
{mainNavPanel}
{sectionNavPanel}
<style jsx>{`
.sliding-nav {
display: flex;
width: 200%;
height: 100%;
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
.sliding-nav.show-main {
transform: translateX(0);
}
.sliding-nav.show-section {
transform: translateX(-50%);
}
/* On desktop, always show section panel when in a section */
@media (min-width: 769px) {
.sliding-nav {
transition: none;
}
.sliding-nav.show-section {
transform: translateX(-50%);
}
}
`}</style>
</div>
)
return (
<>
{/* Desktop sidebar */}
<nav className="sidenav sidenav-desktop">{navContent}</nav>
{/* Mobile overlay */}
<div className={`sidenav-mobile-overlay ${isMobileOpen ? "open" : ""}`} onClick={onMobileClose} />
{/* Mobile sidebar drawer */}
<nav className={`sidenav sidenav-mobile ${isMobileOpen ? "open" : ""}`}>{navContent}</nav>
<style jsx>{`
.sidenav {
background: var(--bg-color);
overflow: hidden;
transition:
background-color 0.2s ease,
border-color 0.2s ease;
}
/* Desktop styles */
.sidenav-desktop {
position: sticky;
top: var(--top-nav-height);
height: calc(100vh - var(--top-nav-height));
flex: 0 0 260px;
border-right: 1px solid var(--border-color);
}
/* Mobile overlay */
.sidenav-mobile-overlay {
display: none;
}
/* Mobile drawer */
.sidenav-mobile {
display: none;
}
/* Mobile styles */
@media (max-width: 768px) {
.sidenav-desktop {
display: none;
}
.sidenav-mobile-overlay {
display: block;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 40;
opacity: 0;
visibility: hidden;
transition:
opacity 0.3s ease,
visibility 0.3s ease;
}
.sidenav-mobile-overlay.open {
opacity: 1;
visibility: visible;
}
.sidenav-mobile {
display: block;
position: fixed;
top: var(--top-nav-height);
left: 0;
width: 300px;
height: calc(100vh - var(--top-nav-height));
z-index: 50;
transform: translateX(-100%);
transition: transform 0.3s ease;
border-right: 1px solid var(--border-color);
}
.sidenav-mobile.open {
transform: translateX(0);
}
}
`}</style>
{/* Global styles for elements that styled-jsx can't reach */}
<style jsx global>{`
.nav-item {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
padding: 0.75rem 1rem;
font-size: 0.9375rem;
font-weight: 500;
text-decoration: none;
color: var(--text-color);
border-radius: 0.5rem;
transition:
background-color 0.15s ease,
color 0.15s ease;
cursor: pointer;
}
.nav-item-button {
background: none;
border: none;
text-align: left;
font-family: inherit;
}
.nav-item:hover {
background-color: var(--bg-secondary);
}
.nav-item.active {
color: var(--accent-color);
}
`}</style>
</>
)
}
+66
View File
@@ -0,0 +1,66 @@
import React from "react"
interface TableProps {
children: React.ReactNode
}
export function Table({ children }: TableProps) {
return (
<div className="overflow-x-auto my-6 border border-neutral-300 dark:border-neutral-700 rounded-lg">
<table className="w-full border-collapse text-sm">{children}</table>
</div>
)
}
interface THeadProps {
children: React.ReactNode
}
export function THead({ children }: THeadProps) {
return <thead className="bg-neutral-100 dark:bg-neutral-800/50">{children}</thead>
}
interface TBodyProps {
children: React.ReactNode
}
export function TBody({ children }: TBodyProps) {
return <tbody className="bg-white dark:bg-neutral-900/50">{children}</tbody>
}
interface TrProps {
children: React.ReactNode
}
export function Tr({ children }: TrProps) {
return <tr className="border-b border-neutral-300 dark:border-neutral-700 last:border-b-0">{children}</tr>
}
interface ThProps {
children: React.ReactNode
width?: string
}
export function Th({ children, width }: ThProps) {
return (
<th
className="px-4 py-2.5 text-left text-sm font-medium text-neutral-700 dark:text-neutral-300"
style={{ width }}>
{children}
</th>
)
}
interface TdProps {
children: React.ReactNode
colspan?: number
rowspan?: number
}
export function Td({ children, colspan, rowspan }: TdProps) {
return (
<td className="px-4 py-3 text-neutral-600 dark:text-neutral-400" colSpan={colspan} rowSpan={rowspan}>
{children}
</td>
)
}
@@ -0,0 +1,83 @@
import React, { useState, useEffect } from "react"
import Link from "next/link"
export function TableOfContents({ toc }) {
const items = toc.filter((item) => item.id && (item.level === 2 || item.level === 3))
const [activeHash, setActiveHash] = useState("")
useEffect(() => {
const updateHash = () => setActiveHash(window.location.hash)
updateHash()
window.addEventListener("hashchange", updateHash)
return () => window.removeEventListener("hashchange", updateHash)
}, [])
if (items.length <= 1) {
return null
}
return (
<nav className="toc">
<ul className="flex column">
{items.map((item) => {
const href = `#${item.id}`
const active = activeHash === href
return (
<li
key={item.title}
className={[active ? "active" : undefined, item.level === 3 ? "padded" : undefined]
.filter(Boolean)
.join(" ")}
>
<Link href={href}>{item.title}</Link>
</li>
)
})}
</ul>
<style jsx>
{`
nav {
position: sticky;
top: 0;
max-height: calc(100vh - var(--top-nav-height) - 6rem);
width: 100%;
align-self: flex-start;
margin-bottom: 1rem;
padding: 0.5rem 0 0;
border-left: 1px solid var(--border-color);
transition: border-color 0.2s ease;
overflow-y: auto;
}
ul {
margin: 0;
padding-left: 1rem;
display: flex;
flex-direction: column;
}
li {
list-style-type: none;
margin: 0 0 1rem;
}
li :global(a) {
text-decoration: none;
color: var(--text-secondary);
}
li :global(a:hover),
li.active :global(a) {
text-decoration: underline;
}
li.padded {
padding-left: 1rem;
}
/* Hide on tablet and mobile */
@media (max-width: 1024px) {
nav {
display: none;
}
}
`}
</style>
</nav>
)
}
+43
View File
@@ -0,0 +1,43 @@
import React, { useState, Children, isValidElement, ReactNode, ReactElement } from "react"
interface TabProps {
label: string
children: ReactNode
}
interface TabsProps {
children: ReactNode
}
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),
)
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">
{tabs.map((tab, index) => (
<button
key={index}
className={`px-2 py-2 text-xs sm:px-4 sm:py-2.5 sm:text-sm font-medium transition-colors whitespace-nowrap ${
activeIndex === index
? "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)}>
{tab.props.label}
</button>
))}
</div>
<div className="tabs-content p-3 sm:p-4 bg-white dark:bg-neutral-900/50">{tabs[activeIndex]}</div>
</div>
)
}
@@ -0,0 +1,117 @@
import React, { useEffect, useState } from "react"
type Theme = "light" | "dark" | "system"
export function ThemeToggle() {
const [theme, setTheme] = useState<Theme>("system")
const [mounted, setMounted] = useState(false)
// On mount, read the preference from localStorage or default to 'system'
useEffect(() => {
setMounted(true)
const storedTheme = localStorage.getItem("theme") as Theme | null
if (storedTheme) {
setTheme(storedTheme)
}
}, [])
// Apply the theme to the document
useEffect(() => {
if (!mounted) return
const root = document.documentElement
if (theme === "system") {
localStorage.removeItem("theme")
const systemDark = window.matchMedia("(prefers-color-scheme: dark)").matches
root.classList.toggle("dark", systemDark)
} else {
localStorage.setItem("theme", theme)
root.classList.toggle("dark", theme === "dark")
}
}, [theme, mounted])
// Listen for system preference changes
useEffect(() => {
if (!mounted) return
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)")
const handleChange = (e: MediaQueryListEvent) => {
if (theme === "system") {
document.documentElement.classList.toggle("dark", e.matches)
}
}
mediaQuery.addEventListener("change", handleChange)
return () => mediaQuery.removeEventListener("change", handleChange)
}, [theme, mounted])
const cycleTheme = () => {
const themes: Theme[] = ["system", "light", "dark"]
const currentIndex = themes.indexOf(theme)
const nextIndex = (currentIndex + 1) % themes.length
setTheme(themes[nextIndex])
}
// Avoid hydration mismatch by not rendering until mounted
if (!mounted) {
return (
<button className="theme-toggle" aria-label="Toggle theme" style={{ width: "32px", height: "32px" }}>
<span style={{ opacity: 0 }}>🌙</span>
</button>
)
}
const getIcon = () => {
if (theme === "system") {
return "💻"
}
if (theme === "dark") {
return "🌙"
}
return "☀️"
}
const getLabel = () => {
if (theme === "system") {
return "Using system theme"
}
if (theme === "dark") {
return "Dark mode"
}
return "Light mode"
}
return (
<>
<button onClick={cycleTheme} className="theme-toggle" aria-label={getLabel()} title={getLabel()}>
<span>{getIcon()}</span>
</button>
<style jsx>{`
.theme-toggle {
display: flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
border: 1px solid var(--border-color);
border-radius: 6px;
background: var(--bg-secondary);
cursor: pointer;
font-size: 16px;
transition:
background-color 0.2s ease,
border-color 0.2s ease;
}
.theme-toggle:hover {
background: var(--border-color);
}
.theme-toggle span {
line-height: 1;
}
`}</style>
</>
)
}
+564
View File
@@ -0,0 +1,564 @@
import React, { useState, useRef, useEffect } from "react"
import Link from "next/link"
import { useRouter } from "next/router"
import docsearch from "@docsearch/js"
import { ThemeToggle } from "./ThemeToggle"
interface NavItem {
label: string
href: string
}
interface DropdownItem {
label: string
href: string
description?: string
}
interface DropdownMenuProps {
label: string
items: DropdownItem[]
isOpen: boolean
onToggle: () => void
onClose: () => void
}
const mainNavItems: NavItem[] = [
{ label: "Get Started", href: "/getting-started" },
{ label: "Code with AI", href: "/code-with-ai" },
{ label: "Customize", href: "/customize" },
{ label: "Collaborate", href: "/collaborate" },
{ label: "Automate", href: "/automate" },
{ label: "Deploy & Secure", href: "/deploy-secure" },
{ label: "Kilo Gateway", href: "/gateway" },
{ label: "Contributing", href: "/contributing" },
]
const contributingItems: DropdownItem[] = [
{ label: "Contributing Guide", href: "/contributing", description: "How to contribute to Kilo Code" },
{
label: "Code of Conduct",
href: "https://github.com/Kilo-Org/kilocode?tab=coc-ov-file",
description: "Our community guidelines",
},
{ label: "GitHub Repository", href: "https://github.com/Kilo-Org/", description: "View source and issues" },
{ label: "Discord Community", href: "https://kilo.ai/discord", description: "Join our community" },
]
const helpItems: DropdownItem[] = [
{ label: "Documentation", href: "/", description: "Browse all documentation" },
{ label: "FAQ", href: "/getting-started/faq", description: "Frequently asked questions" },
{ label: "Community Projects", href: "/community", description: "Explore community resources" },
{ label: "Support", href: "https://kilo.ai/support", description: "Get help from the team" },
{
label: "Changelog",
href: "https://github.com/Kilo-Org/kilocode/releases",
description: "Latest updates and releases",
},
]
function ChevronDownIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="12"
height="12"
viewBox="0 0 12 12"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M2.5 4.5L6 8L9.5 4.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
function SparkleIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="16"
height="16"
viewBox="0 0 16 16"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M8 1V3M8 13V15M3 8H1M15 8H13M12.5 3.5L11 5M5 11L3.5 12.5M12.5 12.5L11 11M5 5L3.5 3.5"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
function SearchIcon({ className }: { className?: string }) {
return (
<svg
className={className}
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg">
<path
d="M9 17C13.4183 17 17 13.4183 17 9C17 4.58172 13.4183 1 9 1C4.58172 1 1 4.58172 1 9C1 13.4183 4.58172 17 9 17Z"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M19 19L14.65 14.65"
stroke="currentColor"
strokeWidth="2"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
)
}
function HamburgerIcon({ isOpen }: { isOpen: boolean }) {
return (
<div className={`hamburger ${isOpen ? "open" : ""}`}>
<span />
<span />
<span />
</div>
)
}
function DropdownMenu({ label, items, isOpen, onToggle, onClose }: DropdownMenuProps) {
const dropdownRef = useRef<HTMLDivElement>(null)
useEffect(() => {
function handleClickOutside(event: MouseEvent) {
if (dropdownRef.current && !dropdownRef.current.contains(event.target as Node)) {
onClose()
}
}
if (isOpen) {
document.addEventListener("mousedown", handleClickOutside)
}
return () => {
document.removeEventListener("mousedown", handleClickOutside)
}
}, [isOpen, onClose])
return (
<div ref={dropdownRef} className="relative">
<button
onClick={onToggle}
className="flex items-center gap-1 px-3 py-2 text-sm font-medium transition-colors hover:text-[var(--text-color)]"
style={{ color: "var(--text-secondary)" }}>
{label}
<ChevronDownIcon className={`transition-transform ${isOpen ? "rotate-180" : ""}`} />
</button>
{isOpen && (
<div
className="absolute right-0 top-full mt-2 w-64 rounded-lg border shadow-lg z-50"
style={{
backgroundColor: "var(--bg-color)",
borderColor: "var(--border-color)",
}}>
<div className="py-2">
{items.map((item) => (
<Link
key={item.href}
href={item.href}
onClick={onClose}
className="block px-4 py-2.5 hover:bg-[var(--bg-secondary)] transition-colors">
<span className="block text-sm font-medium" style={{ color: "var(--text-color)" }}>
{item.label}
</span>
{item.description && (
<span className="block text-xs mt-0.5" style={{ color: "var(--text-secondary)" }}>
{item.description}
</span>
)}
</Link>
))}
</div>
</div>
)}
</div>
)
}
function NavTab({ item, isActive }: { item: NavItem; isActive: boolean }) {
return (
<Link
href={item.href}
className={`relative px-1 py-3 text-sm font-medium transition-colors ${
isActive ? "text-indigo-600 dark:text-[#F8F675]" : "hover:text-[var(--text-color)]"
}`}
style={{ color: isActive ? "var(--text-brand)" : "var(--text-secondary)" }}>
{item.label}
{isActive && <span className="absolute bottom-0 left-0 right-0 h-0.5 bg-indigo-600 dark:bg-[#F8F675]" />}
</Link>
)
}
interface TopNavProps {
onMobileMenuToggle?: () => void
isMobileMenuOpen?: boolean
showMobileMenuButton?: boolean
}
export function TopNav({ onMobileMenuToggle, isMobileMenuOpen = false, showMobileMenuButton = true }: TopNavProps) {
const router = useRouter()
const [openDropdown, setOpenDropdown] = useState<string | null>(null)
const handleDropdownToggle = (name: string) => {
setOpenDropdown(openDropdown === name ? null : name)
}
const handleDropdownClose = () => {
setOpenDropdown(null)
}
const isActiveTab = (href: string) => {
if (href === "/docs") {
return router.pathname === "/docs" || router.pathname === "/docs/index"
}
return router.pathname.startsWith(href)
}
// Open DocSearch modal programmatically
const openDocSearch = () => {
const searchButton = document.querySelector(".DocSearch-Button") as HTMLButtonElement
if (searchButton) {
searchButton.click()
}
}
// Initialize DocSearch
useEffect(() => {
docsearch({
container: "#docsearch",
appId: process.env.NEXT_PUBLIC_ALGOLIA_APP_ID || "PMZUYBQDAK",
indexName: process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME || "docsearch",
apiKey: process.env.NEXT_PUBLIC_ALGOLIA_API_KEY || "24b09689d5b4223813d9b8e48563c8f6",
askAi: process.env.NEXT_PUBLIC_ALGOLIA_ASSISTANT_ID || "askAIDemo",
})
}, [])
return (
<header className="top-header">
{/* Top bar */}
<div className="top-bar">
{/* Mobile menu button */}
{showMobileMenuButton && (
<button className="mobile-menu-btn" onClick={onMobileMenuToggle} aria-label="Toggle menu">
<HamburgerIcon isOpen={isMobileMenuOpen} />
</button>
)}
<Link href="/" className="logo-link flex gap-2 items-center">
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
className="logo-icon"
aria-label="Kilo Code Logo">
<path
fill="currentColor"
d="M0,0v100h100V0H0ZM92.5925926,92.5925926H7.4074074V7.4074074h85.1851852v85.1851852ZM61.1111044,71.9096084h9.2592593v7.4074074h-11.6402116l-5.026455-5.026455v-11.6402116h7.4074074v9.2592593ZM77.7777711,71.9096084h-7.4074074v-9.2592593h-9.2592593v-7.4074074h11.6402116l5.026455,5.026455v11.6402116ZM46.2962963,61.1114207h-7.4074074v-7.4074074h7.4074074v7.4074074ZM22.2222222,53.7040133h7.4074074v16.6666667h16.6666667v7.4074074h-19.047619l-5.026455-5.026455v-19.047619ZM77.7777711,38.8888889v7.4074074h-24.0740741v-7.4074074h8.2781918v-9.2592593h-8.2781918v-7.4074074h10.6591442l5.026455,5.026455v11.6402116h8.3884749ZM29.6296296,30.5555556h9.2592593l7.4074074,7.4074074v8.3333333h-7.4074074v-8.3333333h-9.2592593v8.3333333h-7.4074074v-24.0740741h7.4074074v8.3333333ZM46.2962963,30.5555556h-7.4074074v-8.3333333h7.4074074v8.3333333Z"
/>
</svg>
<div>
<span className="logo-text font-brand">Kilo Code</span>
<span className="docs-label">DOCS</span>
</div>
</Link>
{/* Center - Search and Ask AI (desktop only) */}
<div className="search-container desktop-nav">
<div id="docsearch" />
{/* <button className="ask-ai-btn">
Ask AI
<SparkleIcon className="w-4 h-4" />
</button> */}
</div>
<div className="right-actions">
{/* Mobile search button */}
<button
className="mobile-search-btn mobile-only"
onClick={openDocSearch}
aria-label="Search documentation">
<SearchIcon />
</button>
<ThemeToggle />
<Link href="https://kilo.ai/github" className="github-link desktop-nav">
GitHub
</Link>
<Link href="https://app.kilo.ai" className="signin-btn desktop-nav">
Sign in
</Link>
</div>
</div>
{/* Secondary nav bar (desktop only) */}
<div className="secondary-bar desktop-nav">
<nav className="main-nav">
{mainNavItems.map((item) => (
<NavTab key={item.href} item={item} isActive={isActiveTab(item.href)} />
))}
</nav>
<div className="dropdown-container">
<DropdownMenu
label="Contributing"
items={contributingItems}
isOpen={openDropdown === "contributing"}
onToggle={() => handleDropdownToggle("contributing")}
onClose={handleDropdownClose}
/>
<DropdownMenu
label="Help"
items={helpItems}
isOpen={openDropdown === "help"}
onToggle={() => handleDropdownToggle("help")}
onClose={handleDropdownClose}
/>
</div>
</div>
{/* Announcement banner */}
<div className="announcement-banner">
<p>
We're{" "}
<Link href="https://blog.kilo.ai/p/kilo-cli">replatforming our extensions on the new Kilo CLI</Link>
. Contribute to the new CLI and pre-release extensions at{" "}
<Link href="https://github.com/Kilo-Org/kilo">Kilo-Org/kilo</Link>.
</p>
</div>
<style jsx>{`
.top-header {
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 50;
background-color: var(--bg-color);
transition: background-color 0.2s ease;
}
.top-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0.75rem 1.5rem;
border-bottom: 1px solid var(--border-color);
transition: border-color 0.2s ease;
}
.mobile-menu-btn {
display: none;
align-items: center;
justify-content: center;
padding: 0.5rem;
background: transparent;
border: none;
cursor: pointer;
margin-right: 0.75rem;
}
.logo-link {
align-items: center;
flex-wrap: nowrap;
text-decoration: none;
}
.logo-icon {
display: inline-block;
width: 1.5rem;
height: 1.5rem;
color: var(--text-brand);
}
.logo-text {
font-size: 1.125rem;
font-weight: 600;
letter-spacing: -0.025em;
}
.docs-label {
font-size: 1rem;
font-weight: 300;
margin-left: 0.5rem;
color: var(--text-secondary);
}
.search-container {
display: flex;
align-items: center;
gap: 0.75rem;
}
.ask-ai-btn {
display: flex;
align-items: center;
gap: 0.5rem;
padding: 0.375rem 0.75rem;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
background-color: var(--bg-secondary);
color: var(--text-secondary);
font-size: 0.875rem;
font-weight: 500;
cursor: pointer;
transition: border-color 0.15s ease;
}
.ask-ai-btn:hover {
border-color: #9ca3af;
}
.right-actions {
display: flex;
align-items: center;
gap: 1rem;
}
.github-link {
font-size: 0.875rem;
font-weight: 500;
color: var(--text-secondary);
text-decoration: none;
transition: color 0.15s ease;
}
.github-link:hover {
color: var(--text-color);
}
.signin-btn {
padding: 0.375rem 0.75rem;
font-size: 0.875rem;
font-weight: 500;
border-radius: 0.5rem;
border: 1px solid var(--border-color);
color: var(--text-color);
text-decoration: none;
transition: background-color 0.15s ease;
}
.signin-btn:hover {
background-color: var(--bg-secondary);
}
.secondary-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 1.5rem;
border-bottom: 1px solid var(--border-color);
transition: border-color 0.2s ease;
}
.main-nav {
display: flex;
align-items: center;
gap: 1.5rem;
}
.dropdown-container {
display: flex;
align-items: center;
gap: 0.5rem;
}
.mobile-search-btn {
display: none;
align-items: center;
justify-content: center;
padding: 0.5rem;
background: transparent;
border: none;
cursor: pointer;
color: var(--text-secondary);
transition: color 0.15s ease;
}
.mobile-search-btn:hover {
color: var(--text-color);
}
/* Mobile styles */
@media (max-width: 768px) {
.top-bar {
padding: 0.75rem 1rem;
}
.mobile-menu-btn {
display: flex;
}
.mobile-search-btn {
display: flex;
}
.mobile-only {
display: flex;
}
.logo-icon {
display: none;
}
.docs-label {
display: inline;
}
.desktop-nav {
display: none !important;
}
.right-actions {
gap: 0.5rem;
}
}
.announcement-banner {
background: #1a1a18;
color: #a3a3a2;
padding: 0.5rem 1rem;
text-align: center;
font-size: 0.875rem;
border-bottom: 1px solid #3f3f3f;
}
.announcement-banner p {
margin: 0;
}
.announcement-banner :global(a) {
color: #f8f674;
text-decoration: underline;
text-underline-offset: 2px;
}
.announcement-banner :global(a:hover) {
color: #ffff8d;
}
@media (max-width: 768px) {
.announcement-banner {
font-size: 0.8rem;
}
}
`}</style>
</header>
)
}
+91
View File
@@ -0,0 +1,91 @@
import React from "react"
interface YouTubeProps {
url: string
title?: string
caption?: string
}
/**
* Extracts the YouTube video ID from various URL formats
*/
function extractVideoId(url: string): string | null {
const patterns = [
/(?:youtube\.com\/watch\?v=)([^&\s]+)/,
/(?:youtube\.com\/embed\/)([^?\s]+)/,
/(?:youtu\.be\/)([^?\s]+)/,
/(?:youtube\.com\/v\/)([^?\s]+)/,
]
for (const pattern of patterns) {
const match = url.match(pattern)
if (match) {
return match[1]
}
}
return null
}
export function YouTube({ url, title = "YouTube video", caption }: YouTubeProps) {
const videoId = extractVideoId(url)
if (!videoId) {
return (
<div
style={{
padding: "1rem",
backgroundColor: "var(--red-100, #fee2e2)",
color: "var(--red-700, #b91c1c)",
borderRadius: "0.5rem",
margin: "1.5rem 0",
}}>
Invalid YouTube URL: {url}
</div>
)
}
return (
<div
style={{
maxWidth: "640px",
margin: "1.5rem 0",
}}>
<div
style={{
position: "relative",
paddingBottom: "56.25%", // 16:9 aspect ratio
height: 0,
overflow: "hidden",
borderRadius: "0.5rem",
}}>
<iframe
src={`https://www.youtube.com/embed/${videoId}`}
title={title}
style={{
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
border: "none",
borderRadius: "0.5rem",
}}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
</div>
{caption && (
<figcaption
style={{
fontStyle: "italic",
textAlign: "center",
marginTop: "0.5rem",
color: "var(--gray-600, #6b7280)",
}}>
{caption}
</figcaption>
)}
</div>
)
}
+15
View File
@@ -0,0 +1,15 @@
export * from "./Callout"
export * from "./CodeBlock"
export * from "./Codicon"
export * from "./CopyPageButton"
export * from "./Heading"
export * from "./Icon"
export * from "./Image"
export * from "./KiloCodeIcon"
export * from "./SideNav"
export * from "./Table"
export * from "./TableOfContents"
export * from "./Tabs"
export * from "./ThemeToggle"
export * from "./TopNav"
export * from "./YouTube"
@@ -0,0 +1,107 @@
---
title: Dev Container Persistence
description: How to preserve Kilo Code threads and settings in dev containers
---
# Dev Container Persistence
When using Kilo Code in development containers (VS Code Dev Containers, GitHub Codespaces, etc.), your threads and settings can persist across container rebuilds by properly configuring volume mounts.
## Why Persistence Matters
Dev containers are ephemeral by default - when you rebuild the container, all data is lost unless explicitly persisted. Kilo Code stores important data including:
- **Conversation threads**: Your ongoing discussions with Kilo Code
- **Settings**: API configurations, custom modes, and preferences
- **Cache**: Vector store for code indexing and browser tool data
## Required Configuration
The Kilo Code dev container is pre-configured with named volumes to preserve your data. If you're setting up your own dev container, add these mounts to your `devcontainer.json`:
```json
{
"name": "Your Project",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"mounts": [
{
"source": "kilocode-global-storage",
"target": "/root/.vscode-remote/data/User/globalStorage/kilocode.kilo-code",
"type": "volume"
},
{
"source": "kilocode-settings",
"target": "/root/.vscode-remote/data/User/settings",
"type": "volume"
}
]
}
```
## Storage Locations
| Data Type | Container Path |
| ------------ | ------------------------------------------------------------------------- |
| Threads | `/root/.vscode-remote/data/User/globalStorage/kilocode.kilo-code/tasks/` |
| Settings | `/root/.vscode-remote/data/User/settings/` |
| Cache | `/root/.vscode-remote/data/User/globalStorage/kilocode.kilo-code/cache/` |
| Vector Store | `/root/.vscode-remote/data/User/globalStorage/kilocode.kilo-code/vector/` |
## Troubleshooting
### Threads Don't Appear After Rebuild
1. **Check volume attachment**: Ensure the dev container has the volumes attached
2. **Verify volume contents**: Check that the volume contains your data
3. **Rebuild with volumes**: Use `devcontainer rebuild` instead of `devcontainer up --rebuild`
### Volumes Lost
If named volumes are accidentally deleted:
1. Threads cannot be automatically recovered
2. Start new conversations with Kilo Code
3. Consider implementing a backup strategy for important threads
### Manual Backup
To manually back up your threads:
```bash
# Copy thread data from the container
docker cp <container-name>:/root/.vscode-remote/data/User/globalStorage/kilocode.kilo-code ./kilocode-backup
```
## Custom Storage Path
For advanced configurations, you can specify a custom storage path:
1. Add a bind mount to your `devcontainer.json`:
```json
"mounts": [
{
"source": "${localWorkspaceFolder}/.kilocode-data",
"target": "/home/vscode/kilocode-data",
"type": "bind"
}
]
```
2. Set the custom storage path in VS Code settings:
- Open Settings (`Ctrl+,` or `Cmd+,`)
- Search for "Kilo Code: Custom Storage Path"
- Enter: `/home/vscode/kilocode-data`
## Best Practices
1. **Use named volumes** for automatic persistence
2. **Back up important threads** before major container changes
3. **Avoid deleting volumes** during cleanup
4. **Test persistence** by rebuilding and verifying threads remain
## GitHub Codespaces
GitHub Codespaces automatically persists your VS Code settings and extensions. For Kilo Code threads, the pre-configured dev container includes the necessary volume mounts.
If using a custom Codespace configuration, ensure the mounts from the Required Configuration section are included.
@@ -0,0 +1,315 @@
---
sidebar_label: Switching from Cline
---
# Migrating from Cline to Kilo
A practical guide for developers switching from Cline to Kilo.
## Why Switch?
**Speed.** The Kilo Platform is designed to reduce friction across the entire development workflow. Beyond feature parity with Cline, Kilo includes Code Reviews, App Builder, Cloud Agents, and one-click Deploy.
**Multi-platform.** Work in VS Code, JetBrains IDEs, CLI, or the web. Your Sessions sync across all of them automatically.
**Specialized modes.** Instead of one agent doing everything, Kilo has five specialized modes optimized for different parts of your workflow.
**500+ models.** More providers, more options, better pricing flexibility. Switch models mid-conversation if you want.
---
## Understanding Kilo's Mode System
Cline uses a single agent with a Plan/Act toggle. Kilo takes a different approach: five specialized modes, each optimized for a specific part of development. You select modes from a dropdown in the interface in the Kilo Extension, or with slash commands in the CLI.
### Kilo's Five Modes
#### Code Mode (default)
- **What it does:** Implementation and refactoring
- **Cline equivalent:** Act mode
- **When to use:** Writing features, fixing bugs, making changes
- **Example:** "Add user authentication to the API"
#### Ask Mode
- **What it does:** Answers questions, explains code
- **Cline equivalent:** Plan mode (read-only exploration)
- **When to use:** Understanding codebases, learning patterns
- **Example:** "How does our caching layer work?"
#### Debug Mode
- **What it does:** Systematic troubleshooting and error diagnosis
- **Cline equivalent:** Act mode focused on debugging
- **When to use:** Tracking down bugs, fixing runtime issues
- **Example:** "Why is this API endpoint returning 500?"
#### Architect Mode
- **What it does:** Planning, design, and technical leadership
- **Cline equivalent:** Plan mode (exploration and planning)
- **When to use:** Before complex refactors, designing new systems
- **Example:** "Design a caching strategy for our API"
#### Orchestrator Mode
- **What it does:** Breaks down complex tasks, coordinates other modes
- **Cline equivalent:** Complex multi-step workflows
- **When to use:** Large features spanning multiple systems
- **Example:** "Build a complete user management system"
### Mode Switching in Action
**Cline workflow:** Toggle Plan/Act → Submit task → Plan phase → Approve → Act phase → Checkpoint
**Kilo workflow:**
Select mode from dropdown → Build → Switch modes as needed → Checkpoint → Session auto-saves
Or
Select Orchestrator mode → autonomously define subtasks → intelligently distribute subtasks across modes
#### Example: Refactoring authentication
**Cline:**
1. Enable Plan/Act mode
2. "Refactor auth to use OAuth2"
3. Wait for plan → Review → Approve
4. Watch step-by-step execution
5. Checkpoint when done
**Kilo:**
1. Select **Orchestrator** from the mode dropdown
2. "Implement OAuth2 refactor for our authentication"
3. Orchestrator creates subtasks for other modes automatically
4. **Architect Mode** reviews the architecture
5. **Code Mode** implements the OAuth2 client
6. Session/checkpoints preserved automatically
#### Example: Understanding unfamiliar code
**Cline:** Use Plan mode (but risk accidentally switching to Act)
**Kilo:** Select **Ask** from the dropdown
- "Explain how the payment processing flow works"
- "What external services does this integrate with?"
- Ask mode never writes files, so exploration is always safe
**Why this matters:** In Cline, you might accidentally make changes while exploring. In Kilo, Ask and Architect modes can't write files, so you're safe to explore without worry. Kilo's **Orchestrator** mode lets you intelligently generate and execute subtasks that are optimized for each mode.
---
## Installation
### VS Code / Cursor
1. Open Extensions (`Cmd/Ctrl + Shift + X`)
2. Search "Kilo Code"
3. Click Install
4. Find the Kilo icon in your sidebar
### JetBrains IDEs
Supports IntelliJ, PyCharm, WebStorm, and all JetBrains IDEs.
**Prerequisites:**
- JetBrains Toolbox (required for auth)
- Node.js LTS
**Install:**
1. Settings → Plugins → Marketplace
2. Search "Kilo Code"
3. Install and restart
4. Find Kilo icon in right sidebar
### CLI
```shell
npm install -g @kilocode/cli
kilo
```
### Web (Cloud Agents & App Builder)
Visit [app.kilo.ai](https://app.kilo.ai/) and sign in. This gives you access to:
- **Cloud Agents:** Run Kilo without a local machine
- **App Builder:** Build and preview apps directly in your browser
- **Kilo Deploy:** One-click deployments
- **Code Reviews:** AI-powered PR analysis
---
## Initial Setup
### Create account
1. Click "Try Kilo Code for Free" in the Kilo panel
2. Sign in with OAuth at kilo.ai
3. You'll be redirected back to your IDE
### Configure your provider
**Option 1: Use Kilo Gateway (easiest)**
1. Open settings (⚙️ icon)
2. Select "Kilo Gateway" as provider
3. Choose a model (such as Claude Opus 4.5, Gemini 3, MiniMax M2.1)
**Option 2: Bring your own API keys**
1. Select your provider (Anthropic, OpenAI, etc.)
2. Enter your API key
3. Choose your model
---
## Beyond the IDE: Kilo's Platform Features
One of the biggest differences from Cline is that Kilo isn't just an IDE extension. It's a platform with multiple interfaces that can all share your Sessions and context.
### Cloud Agents
Run Kilo from [app.kilo.ai/cloud](https://app.kilo.ai/cloud) without needing your local machine. Great for:
- Working from a tablet or phone
- Offloading heavy tasks
- Parallel execution without blocking your IDE
### Parallel Agents
Run multiple agents simultaneously without conflicts, in both the IDE and CLI. Start an agent working on tests while another handles documentation.
### Sessions
Your conversation history, context, and state sync across all interfaces automatically. Start a task in the CLI, continue in VS Code, check progress on mobile.
### App Builder
Build live apps and sites directly from the web with a real-time preview. Similar to Lovable, but integrated with your Kilo Sessions. Deploy with one click when you're ready.
### Kilo Deploy
One-click deployments from directly within Kilo. Go from code to production without leaving your workflow.
### Code Reviews
Automatically analyzes your PRs using your choice of AI model. Reviews happen the moment a PR is opened or updated, covering performance, security, style, and test coverage.
### Managed Indexing
Semantic search across your repositories using cloud-hosted embeddings. Kilo indexes your codebase to deliver more relevant, context-aware responses.
### Autocomplete
In-line ghost-text completions with tab to complete. Works alongside the agent modes for a complete coding experience.
---
## Complete Development Workflows
### New Feature Development
**Kilo approach:**
1. **Architect mode:** "Design a user notification system"
2. Review architecture, discuss trade-offs
3. **Code mode:** "Implement the notification service"
4. Fast Apply builds it quickly
5. **Debug mode:** "Email sends aren't working"
6. Fix issues
7. Session auto-saves as "Notifications-Complete"
### Debugging Production Issues
**Kilo approach:**
1. **Debug mode:** "Checkout fails with 'payment_intent_not_found'"
2. Debug mode systematically checks logs, traces API calls
3. **Code mode:** "Add idempotency key to prevent duplicates"
4. Verify fix
### Large Refactoring
**Kilo approach:**
1. **Ask mode:** "Explain our current auth implementation"
2. **Architect mode:** "Design migration to JWT tokens"
3. Session saves as "Auth-Refactor-Plan"
4. **Code mode:** Implement JWT generation, update middleware
5. **Debug mode:** Fix failing tests
### Learning Unfamiliar Code
**Kilo approach:**
1. **Ask mode:** "Explain how payment processing works"
2. "What happens when a payment fails?"
3. "Show me the retry logic"
4. Ask mode never writes, so exploration is completely safe
5. When ready, switch to **Code mode** to make changes
---
## Feature Mapping
| Cline Feature | Kilo Equivalent | Notes |
| ------------------ | ---------------------------------- | ------------------------------------------------------------------------------- |
| Plan mode | Orchestrator, Architect, Ask modes | Architect plans, Ask explains, Orchestrate distributes tasks across other modes |
| Act mode | Code mode | Implementation |
| Plan/Act toggle | Mode dropdown | More granular control |
| Checkpoints | Sessions + Checkpoints | Sessions preserve mode + context |
| Background editing | Fast Apply | Sequential but instant |
| Single agent | Five specialized modes | Purpose-built for each task |
| Local only | Multi-platform | IDE, CLI, web, mobile |
---
## What You Gain
- **Specialized modes:** Purpose-built for different parts of development
- **Fast Apply:** 5-10x faster code application
- **Autocomplete:** Inline AI suggestions
- **Multi-platform:** VS Code, JetBrains, CLI, web
- **Session Persistance:** Sessions preserve mode + context across devices
- **500+ models:** More provider options, switch anytime
- **Cloud Agents:** Work without your local machine
- **App Builder:** Build and preview apps in the browser
- **One-click Deploy:** Ship directly from Kilo
- **Code Reviews:** AI-powered PR analysis
- **Parallel Agents:** Run multiple agents simultaneously
---
## Common Questions
**Q: Do I have to switch modes constantly?** No. Orchestrator does that automatically. Code mode handles most day-to-day work. Switch when you need specialized behavior.
**Q: What if I forget to switch modes?** Code mode is the default and handles most tasks. It'll still work, just might not be optimized for exploration or planning.
**Q: Can I customize what each mode does?** Yes. Add mode-specific instructions in settings, or create custom modes.
**Q: Can I use both Cline and Kilo side-by-side?** Yes. They're separate extensions.
**Q: What's the difference between Cloud Agents and the IDE extension?** Same capabilities, different interface. Cloud Agents run in the browser, so you can work from any device without your local machine.
---
## Next Steps
1. Install Kilo in your primary IDE
2. Try each mode with a small task:
- **Code:** "Add a hello world endpoint"
- **Ask:** "Explain what this file does"
- **Debug:** "Why is this function returning undefined?"
- **Architect:** "Design a logging system"
- **Orchestrator:** "Build an app, end-to-end, that…"
3. Try Cloud Agents at [app.kilo.ai](https://app.kilo.ai/)
4. Install the Kilo CLI with `npm install -g @kilocode/cli`
5. Enable Autocomplete for inline suggestions
@@ -0,0 +1,10 @@
import posthog from "posthog-js"
if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
posthog.init(process.env.NEXT_PUBLIC_POSTHOG_KEY, {
api_host: process.env.NEXT_PUBLIC_POSTHOG_HOST,
person_profiles: "identified_only",
capture_pageview: false, // Handled manually in _app.tsx on routeChangeComplete
capture_pageleave: true,
})
}
@@ -0,0 +1,85 @@
import { NavSection } from "../types"
export const AiProvidersNav: NavSection[] = [
{
title: "AI Providers",
links: [
{ href: "/ai-providers", children: "Overview" },
{ href: "/ai-providers/kilocode", children: "Kilo Code (Default)" },
],
},
{
title: "AI Labs",
links: [
{ href: "/ai-providers/anthropic", children: "Anthropic" },
{ href: "/ai-providers/claude-code", children: "Claude Code" },
{ href: "/ai-providers/openai", children: "OpenAI" },
{
href: "/ai-providers/openai-chatgpt-plus-pro",
children: "ChatGPT Plus/Pro",
},
{ href: "/ai-providers/gemini", children: "Google Gemini" },
{ href: "/ai-providers/mistral", children: "Mistral AI" },
{ href: "/ai-providers/deepseek", children: "DeepSeek" },
{ href: "/ai-providers/xai", children: "xAI (Grok)" },
],
},
{
title: "AI Gateways",
links: [
{ href: "/ai-providers/openrouter", children: "OpenRouter" },
{ href: "/ai-providers/glama", children: "Glama" },
{ href: "/ai-providers/requesty", children: "Requesty" },
{ href: "/ai-providers/unbound", children: "Unbound" },
{
href: "/ai-providers/vercel-ai-gateway",
children: "Vercel AI Gateway",
},
],
},
{
title: "Cloud Providers",
links: [
{ href: "/ai-providers/vertex", children: "Google Vertex AI" },
{ href: "/ai-providers/bedrock", children: "AWS Bedrock" },
{ href: "/ai-providers/groq", children: "Groq" },
{ href: "/ai-providers/cerebras", children: "Cerebras" },
{ href: "/ai-providers/fireworks", children: "Fireworks AI" },
],
},
{
title: "Local & Self-Hosted",
links: [
{ href: "/ai-providers/ollama", children: "Ollama" },
{ href: "/ai-providers/lmstudio", children: "LM Studio" },
{ href: "/ai-providers/vscode-lm", children: "VS Code LM API" },
{
href: "/ai-providers/openai-compatible",
children: "OpenAI Compatible",
},
],
},
{
title: "Other Providers",
links: [
{ href: "/ai-providers/chutes-ai", children: "Chutes AI" },
{ href: "/ai-providers/inception", children: "Inception" },
{ href: "/ai-providers/minimax", children: "MiniMax" },
{ href: "/ai-providers/moonshot", children: "Moonshot" },
{ href: "/ai-providers/ovhcloud", children: "OVHcloud" },
{ href: "/ai-providers/sap-ai-core", children: "SAP AI Core" },
],
},
{
title: "Special Modes",
links: [
{ href: "/ai-providers/v0", children: "v0" },
{ href: "/ai-providers/human-relay", children: "Human Relay" },
{ href: "/ai-providers/synthetic", children: "Synthetic Provider" },
{
href: "/ai-providers/virtual-quota-fallback",
children: "Virtual Quota Fallback",
},
],
},
]
+61
View File
@@ -0,0 +1,61 @@
import { NavSection } from "../types"
export const AutomateNav: NavSection[] = [
{
title: "Agents",
links: [
{ href: "/automate", children: "Overview" },
{ href: "/automate/integrations", children: "Integrations" },
{
href: "/automate/code-reviews/overview",
children: "Code Reviews",
subLinks: [
{ href: "/automate/code-reviews/overview", children: "Overview" },
{ href: "/automate/code-reviews/github", children: "GitHub" },
{ href: "/automate/code-reviews/gitlab", children: "GitLab" },
],
},
{ href: "/automate/agent-manager", children: "Agent Manager" },
{ href: "/automate/kiloclaw", children: "KiloClaw" },
],
},
{
title: "Extending Kilo",
links: [
{ href: "/automate/extending/local-models", children: "Local Models" },
{
href: "/automate/extending/shell-integration",
children: "Shell Integration",
},
{
href: "/automate/extending/auto-launch",
children: "Auto-launch Configuration",
},
{
href: "/automate/mcp/overview",
children: "MCP",
subLinks: [
{ href: "/automate/mcp/overview", children: "MCP Overview" },
{
href: "/automate/mcp/using-in-kilo-code",
children: "Using MCP in Kilo Code",
},
{ href: "/automate/mcp/using-in-cli", children: "Using MCP in CLI" },
{ href: "/automate/mcp/what-is-mcp", children: "What is MCP" },
{
href: "/automate/mcp/server-transports",
children: "Server Transports",
},
{ href: "/automate/mcp/mcp-vs-api", children: "MCP vs API" },
],
},
],
},
{
title: "Tools",
links: [
{ href: "/automate/how-tools-work", children: "How Tools Work" },
{ href: "/automate/tools", children: "Tools Details" },
],
},
]
@@ -0,0 +1,89 @@
import { NavSection } from "../types"
export const CodeWithAiNav: NavSection[] = [
{
title: "Platforms",
links: [
{ href: "/code-with-ai", children: "Overview" },
{ href: "/code-with-ai/platforms/vscode", children: "VS Code Extension" },
{
href: "/code-with-ai/platforms/jetbrains",
children: "JetBrains Extension",
},
{ href: "/code-with-ai/platforms/cli", children: "CLI" },
{ href: "/code-with-ai/platforms/cloud-agent", children: "Cloud Agent" },
{ href: "/code-with-ai/platforms/mobile", children: "Mobile Apps" },
{ href: "/code-with-ai/platforms/slack", children: "Slack" },
{ href: "/code-with-ai/app-builder", children: "App Builder" },
],
},
{
title: "Chat & Context",
links: [
{
href: "/code-with-ai/agents/chat-interface",
children: "Chat Interface",
},
{
href: "/code-with-ai/agents/context-mentions",
children: "Context & Mentions",
},
{
href: "/code-with-ai/agents/model-selection",
children: "Model Selection",
},
{
href: "/code-with-ai/agents/auto-model",
children: "Auto Model",
},
{
href: "/code-with-ai/agents/free-and-budget-models",
children: "Free & Budget Models",
},
{
href: "/code-with-ai/agents/using-modes",
children: "Modes",
subLinks: [
{ href: "/code-with-ai/agents/using-modes", children: "Using Modes" },
{
href: "/code-with-ai/agents/orchestrator-mode",
children: "Orchestrator Mode",
},
],
},
],
},
{
title: "Productivity Tools",
links: [
{
href: "/code-with-ai/features/autocomplete",
children: "Autocomplete",
subLinks: [{ href: "/code-with-ai/features/autocomplete/mistral-setup", children: "Mistral Setup" }],
},
{ href: "/code-with-ai/features/code-actions", children: "Code Actions" },
{
href: "/code-with-ai/features/enhance-prompt",
children: "Enhance Prompt",
},
{
href: "/code-with-ai/features/git-commit-generation",
children: "Git Commit Generation",
},
{ href: "/code-with-ai/features/speech-to-text", children: "Voice Transcription" },
{
href: "/code-with-ai/features/browser-use",
children: "Agent Behavior",
subLinks: [
{ href: "/code-with-ai/features/browser-use", children: "Browser Use" },
{ href: "/code-with-ai/features/fast-edits", children: "Fast Edits" },
{
href: "/code-with-ai/features/task-todo-list",
children: "Task Todo List",
},
{ href: "/code-with-ai/features/checkpoints", children: "Checkpoints" },
],
},
],
},
]
+66
View File
@@ -0,0 +1,66 @@
import { NavSection } from "../types"
export const CollaborateNav: NavSection[] = [
{
title: "Sharing",
links: [
{ href: "/collaborate", children: "Overview" },
{ href: "/collaborate/sessions-sharing", children: "Sessions & Sharing" },
],
},
{
title: "Kilo for Teams",
links: [
{ href: "/collaborate/teams/about-plans", children: "About Plans" },
{
href: "/collaborate/teams/getting-started",
children: "Getting Started with Teams",
},
{ href: "/collaborate/teams/dashboard", children: "Dashboard" },
{
href: "/collaborate/teams/team-management",
children: "Team Management",
},
{
href: "/collaborate/teams/custom-modes-org",
children: "Custom Modes (Org)",
},
{ href: "/collaborate/teams/billing", children: "Billing" },
{ href: "/collaborate/teams/analytics", children: "Analytics" },
{
href: "/collaborate/adoption-dashboard/overview",
children: "AI Adoption Dashboard",
subLinks: [
{
href: "/collaborate/adoption-dashboard/overview",
children: "Overview",
},
{
href: "/collaborate/adoption-dashboard/understanding-your-score",
children: "Understanding Your Score",
},
{
href: "/collaborate/adoption-dashboard/improving-your-score",
children: "Improving Your Score",
},
{
href: "/collaborate/adoption-dashboard/for-team-leads",
children: "For Team Leads",
},
],
},
],
},
{
title: "Enterprise",
links: [
{ href: "/collaborate/enterprise/sso", children: "SSO" },
{
href: "/collaborate/enterprise/model-access-controls",
children: "Model Access Controls",
},
{ href: "/collaborate/enterprise/audit-logs", children: "Audit Logs" },
{ href: "/collaborate/enterprise/migration", children: "Migration" },
],
},
]
@@ -0,0 +1,85 @@
import { NavSection } from "../types"
export const ContributingNav: NavSection[] = [
{
title: "Getting Started",
links: [
{ href: "/contributing", children: "Contributing Overview" },
{
href: "/contributing/development-environment",
children: "Development Environment",
},
{
href: "/contributing/ecosystem",
children: "Ecosystem",
},
{
href: "/contributing/cline-to-kilo-migration",
children: "Cline to Kilo Migration",
},
],
},
{
title: "Architecture",
links: [
{
href: "/contributing/architecture",
children: "Architecture Overview",
},
{
href: "/contributing/architecture/features",
children: "Features",
subLinks: [
{
href: "/contributing/architecture/agent-observability",
children: "Agent Observability",
},
{
href: "/contributing/architecture/annual-billing",
children: "Annual Billing",
},
{
href: "/contributing/architecture/benchmarking",
children: "Benchmarking",
},
{
href: "/contributing/architecture/enterprise-mcp-controls",
children: "Enterprise MCP Controls",
},
{
href: "/contributing/architecture/mcp-oauth-authorization",
children: "MCP OAuth Authorization",
},
{
href: "/contributing/architecture/model-provider-blocklist",
children: "Model/Provider Blocklist",
},
{
href: "/contributing/architecture/onboarding-improvements",
children: "Onboarding Improvements",
},
{
href: "/contributing/architecture/organization-modes-library",
children: "Organization Modes Library",
},
{
href: "/deploy-secure/security-reviews",
children: "Agentic Security Reviews",
},
{
href: "/contributing/architecture/track-repo-url",
children: "Track Repo URL",
},
{
href: "/contributing/architecture/vercel-ai-gateway",
children: "Vercel AI Gateway",
},
{
href: "/contributing/architecture/voice-transcription",
children: "Voice Transcription",
},
],
},
],
},
]
+51
View File
@@ -0,0 +1,51 @@
import { NavSection } from "../types"
export const CustomizeNav: NavSection[] = [
{
title: "Customization",
links: [
{ href: "/customize", children: "Overview" },
{
href: "/customize/custom-modes",
children: "Custom Modes",
},
{
href: "/customize/custom-rules",
children: "Custom Rules",
},
{
href: "/customize/custom-instructions",
children: "Custom Instructions",
},
{ href: "/customize/agents-md", children: "agents.md" },
{ href: "/customize/workflows", children: "Workflows" },
{ href: "/customize/skills", children: "Skills" },
{
href: "/customize/prompt-engineering",
children: "Prompt Engineering",
},
],
},
{
title: "Context & Indexing",
links: [
{
href: "/customize/context/codebase-indexing",
children: "Codebase Indexing",
},
{
href: "/customize/context/context-condensing",
children: "Context Condensing",
},
{
href: "/customize/context/kilocodeignore",
children: ".kilocodeignore",
},
{ href: "/customize/context/memory-bank", children: "Memory Bank" },
{
href: "/customize/context/large-projects",
children: "Large Projects",
},
],
},
]
@@ -0,0 +1,16 @@
import { NavSection } from "../types"
export const DeploySecureNav: NavSection[] = [
{
title: "Deployment",
links: [
{ href: "/deploy-secure", children: "Overview" },
{ href: "/deploy-secure/deploy", children: "Deploy" },
{ href: "/deploy-secure/managed-indexing", children: "Managed Indexing" },
],
},
{
title: "Security",
links: [{ href: "/deploy-secure/security-reviews", children: "Security Reviews" }],
},
]
+32
View File
@@ -0,0 +1,32 @@
import { NavSection } from "../types"
export const GatewayNav: NavSection[] = [
{
title: "Introduction",
links: [
{ href: "/gateway", children: "Overview" },
{ href: "/gateway/quickstart", children: "Quickstart" },
],
},
{
title: "Configuration",
links: [
{ href: "/gateway/authentication", children: "Authentication" },
{ href: "/gateway/models-and-providers", children: "Models & Providers" },
],
},
{
title: "Features",
links: [
{ href: "/gateway/streaming", children: "Streaming" },
{ href: "/gateway/usage-and-billing", children: "Usage & Billing" },
],
},
{
title: "Reference",
links: [
{ href: "/gateway/api-reference", children: "API Reference" },
{ href: "/gateway/sdks-and-frameworks", children: "SDKs & Frameworks" },
],
},
]
@@ -0,0 +1,75 @@
import { NavSection } from "../types"
export const GettingStartedNav: NavSection[] = [
{
title: "Introduction",
links: [
{ href: "/getting-started", children: "Overview" },
{ href: "/getting-started/installing", children: "Installation" },
{ href: "/getting-started/quickstart", children: "Quickstart" },
],
},
{
title: "Configuration",
links: [
{
href: "/getting-started/setup-authentication",
children: "Setup & Authentication",
},
{
href: "/getting-started/using-kilo-for-free",
children: "Using Kilo for Free",
},
{
href: "/getting-started/byok",
children: "Bring Your Own Key (BYOK)",
},
{ href: "/ai-providers", children: "AI Providers" },
{
href: "/getting-started/settings",
children: "Settings",
subLinks: [
{ href: "/getting-started/settings/auto-approving-actions", children: "Auto-Approving Actions" },
{ href: "/getting-started/settings/auto-cleanup", children: "Auto Cleanup" },
{ href: "/getting-started/settings/system-notifications", children: "System Notifications" },
],
},
{ href: "/getting-started/adding-credits", children: "Adding Credits" },
{ href: "/getting-started/rate-limits-and-costs", children: "Rate Limits and Costs" },
],
},
{
title: "Help",
links: [
{
href: "/getting-started/faq",
children: "FAQ",
subLinks: [
{ href: "/getting-started/faq/general", children: "General" },
{ href: "/getting-started/faq/setup-and-installation", children: "Setup and Installation" },
{ href: "/getting-started/faq/credits-and-billing", children: "Credits and Billing" },
{ href: "/getting-started/faq/account-and-integration", children: "Account and Integration" },
{ href: "/getting-started/faq/known-issues", children: "Known Issues" },
],
},
{
href: "/getting-started/migrating",
children: "Migrating from Cursor",
},
{
href: "/getting-started/troubleshooting",
children: "Troubleshooting",
subLinks: [
{
href: "/getting-started/troubleshooting/troubleshooting-extension",
children: "Extension Troubleshooting",
},
],
},
{
href: "/getting-started/using-docs-with-agents",
children: "Using Docs with Agents",
},
],
},
]
+23
View File
@@ -0,0 +1,23 @@
import { AiProvidersNav } from "./ai-providers"
import { AutomateNav } from "./automate"
import { CodeWithAiNav } from "./code-with-ai"
import { CollaborateNav } from "./collaborate"
import { ContributingNav } from "./contributing"
import { CustomizeNav } from "./customize"
import { DeploySecureNav } from "./deploy-secure"
import { GatewayNav } from "./gateway"
import { GettingStartedNav } from "./getting-started"
import { ToolsNav } from "./tools"
export const Nav = {
GettingStartedNav,
CodeWithAiNav,
CustomizeNav,
CollaborateNav,
AutomateNav,
DeploySecureNav,
ContributingNav,
AiProvidersNav,
GatewayNav,
ToolsNav,
}
+51
View File
@@ -0,0 +1,51 @@
import { NavSection } from "../types"
export const ToolsNav: NavSection[] = [
{
title: "Tools",
links: [{ href: "/automate/tools", children: "Overview" }],
},
{
title: "Read Tools",
links: [
{ href: "/automate/tools/read-file", children: "read_file" },
{ href: "/automate/tools/search-files", children: "search_files" },
{ href: "/automate/tools/list-files", children: "list_files" },
{ href: "/automate/tools/list-code-definition-names", children: "list_code_definition_names" },
{ href: "/automate/tools/codebase-search", children: "codebase_search" },
],
},
{
title: "Edit Tools",
links: [
{ href: "/automate/tools/apply-diff", children: "apply_diff" },
{ href: "/automate/tools/delete-file", children: "delete_file" },
{ href: "/automate/tools/write-to-file", children: "write_to_file" },
],
},
{
title: "Browser Tools",
links: [{ href: "/automate/tools/browser-action", children: "browser_action" }],
},
{
title: "Command Tools",
links: [{ href: "/automate/tools/execute-command", children: "execute_command" }],
},
{
title: "MCP Tools",
links: [
{ href: "/automate/tools/use-mcp-tool", children: "use_mcp_tool" },
{ href: "/automate/tools/access-mcp-resource", children: "access_mcp_resource" },
],
},
{
title: "Workflow Tools",
links: [
{ href: "/automate/tools/switch-mode", children: "switch_mode" },
{ href: "/automate/tools/new-task", children: "new_task" },
{ href: "/automate/tools/ask-followup-question", children: "ask_followup_question" },
{ href: "/automate/tools/attempt-completion", children: "attempt_completion" },
{ href: "/automate/tools/update-todo-list", children: "update_todo_list" },
],
},
]
+14
View File
@@ -0,0 +1,14 @@
export interface NavLink {
href: string
children: string
subLinks?: NavLink[] // Optional nested links for second-level navigation
}
export interface NavSection {
title: string
links: NavLink[]
}
export interface SectionNav {
[key: string]: NavSection[]
}
+189
View File
@@ -0,0 +1,189 @@
## Mapping Existing Pages to New Structure
### Get Started
| New Item | Existing Page(s) |
| ------------------------------ | ----------------------------------------------------------------------- |
| Introduction / Overview | `index`, `getting-started/concepts` |
| Installation | `getting-started/installing` |
| Quickstart | `getting-started/your-first-task` |
| Setup & Authentication | `getting-started/setting-up`, `getting-started/connecting-api-provider` |
| AI Providers | `basic-usage/connecting-providers`, `providers/*` (all of them) |
| Settings | `basic-usage/settings-management` |
| Adding Credits | `basic-usage/adding-credits` |
| FAQ | Keep if it exists |
| Migrating from Cursor/Windsurf | `advanced-usage/migrating-from-cursor-windsurf` |
---
### Code with AI
| New Item | Existing Page(s) |
| ----------------------------------- | -------------------------------------------------------------------------- |
| **Platforms** (subheader) | |
| VS Code Extension | Needs new page (or pull from install) |
| JetBrains Extension | Needs new page |
| CLI | `cli` |
| Cloud Agent | `advanced-usage/cloud-agent` (partial) |
| Mobile Apps | Needs new page |
| Slack | `slack` |
| **Working with Agents** (subheader) | |
| The Chat Interface | `basic-usage/the-chat-interface` |
| Context & Mentions | `basic-usage/context-mentions` |
| Using Modes | `basic-usage/using-modes` |
| Orchestrator Mode | `basic-usage/orchestrator-mode` |
| Model Selection | `basic-usage/model-selection-guide` |
| Free & Budget Models | `advanced-usage/free-and-budget-models` |
| **Features** (subheader) | |
| Autocomplete | `basic-usage/autocomplete/index`, `basic-usage/autocomplete/mistral-setup` |
| Code Actions | `features/code-actions` |
| Browser Use | `features/browser-use` |
| Git Commit Generation | `basic-usage/git-commit-generation` |
| Checkpoints | `features/checkpoints` |
| Enhance Prompt | `features/enhance-prompt` |
| Fast Edits | `features/fast-edits` |
| Task Todo List | `basic-usage/task-todo-list` |
| **Context & Indexing** (subheader) | |
| Codebase Indexing | `features/codebase-indexing` |
| Large Projects | `advanced-usage/large-projects` |
| **Customization** (subheader) | |
| Custom Modes | `agent-behavior/custom-modes` |
| Custom Rules | `agent-behavior/custom-rules` |
| Custom Instructions | `agent-behavior/custom-instructions` |
| agents.md | `agent-behavior/agents-md` |
| Workflows | `agent-behavior/workflows` |
| Skills | `agent-behavior/skills` |
| Prompt Engineering | `agent-behavior/prompt-engineering` |
| **App Builder** (subheader) | |
| App Builder | `advanced-usage/appbuilder` |
---
### Collaborate
| New Item | Existing Page(s) |
| ------------------------------------- | --------------------------------------------------- |
| Sessions & Sharing | `advanced-usage/sessions` |
| **Kilo for Teams** (subheader) | |
| About Plans | `plans/about` |
| Getting Started with Teams | `plans/getting-started` |
| Dashboard | `plans/dashboard` |
| Team Management | `plans/team-management` |
| Custom Modes (Org) | `plans/custom-modes` |
| Billing | `plans/billing` |
| Analytics | `plans/analytics` |
| **AI Adoption Dashboard** (subheader) | |
| Overview | `plans/adoption-dashboard/overview` |
| Understanding Your Score | `plans/adoption-dashboard/understanding-your-score` |
| Improving Your Score | `plans/adoption-dashboard/improving-your-score` |
| For Team Leads | `plans/adoption-dashboard/for-team-leads` |
| **Enterprise** (subheader) | |
| SSO | `plans/enterprise/SSO` |
| Model Access Controls | `plans/enterprise/model-access` |
| Audit Logs | `plans/enterprise/audit-logs` |
| Migration | `plans/migration` |
---
### Automate
| New Item | Existing Page(s) |
| ------------------------------ | ------------------------------------- |
| Integrations Overview | `advanced-usage/integrations` |
| Code Reviews | `advanced-usage/code-reviews` |
| Agent Manager | `advanced-usage/agent-manager` |
| **Extending Kilo** (subheader) | |
| Local Models | `advanced-usage/local-models` |
| Shell Integration | `features/shell-integration` |
| Auto-launch Configuration | `features/auto-launch-configuration` |
| **MCP** (subheader) | |
| MCP Overview | `features/mcp/overview` |
| Using MCP in Kilo Code | `features/mcp/using-mcp-in-kilo-code` |
| Using MCP in CLI | `features/mcp/using-mcp-in-cli` |
| What is MCP | `features/mcp/what-is-mcp` |
| Server Transports | `features/mcp/server-transports` |
| MCP vs API | `features/mcp/mcp-vs-api` |
| **Tools (subheader)** | |
| How Tools Work | `basic-usage/how-tools-work` |
| Tool Details | ALL of Tool reference |
---
### Deploy & Secure
| New Item | Existing Page(s) |
| ---------------- | ----------------------------------------------------------------------- |
| Deploy | `advanced-usage/deploy` |
| Managed Indexing | `advanced-usage/managed-indexing` |
| Security Reviews | `contributing/architecture/security-reviews` (move out of contributing) |
---
### Contributing
| New Item | Existing Page(s) |
| ---------------------------- | -------------------------------------------------------------- |
| Contributing Overview | `contributing/index` |
| Development Environment | `contributing/development-environment` |
| **Architecture** (subheader) | |
| Architecture Overview | `contributing/architecture/index` |
| Annual Billing | `contributing/architecture/annual-billing` |
| Enterprise MCP Controls | `contributing/architecture/enterprise-mcp-controls` |
| Onboarding Improvements | `contributing/architecture/onboarding-engagement-improvements` |
| Organization Modes Library | `contributing/architecture/organization-modes-library` |
| Track Repo URL | `contributing/architecture/track-repo-url` |
| Vercel AI Gateway | `contributing/architecture/vercel-ai-gateway` |
| Voice Transcription | `contributing/architecture/voice-transcription` |
---
## Pages to Add (Don't Exist Yet)
| Section | New Page Needed |
| --------------- | --------------------------------------- |
| Get Started | "Choosing Your Surface" (decision tree) |
| Code with AI | VS Code dedicated page |
| Code with AI | JetBrains dedicated page |
| Code with AI | Web App dedicated page |
| Code with AI | Mobile Apps (iOS/Android) |
| Collaborate | Team Workspaces overview |
| Collaborate | Permissions & Roles |
| Automate | Triage Agent |
| Automate | Auto-fix Agent |
| Automate | GitHub Actions guide |
| Automate | Webhooks & Triggers |
| Deploy & Secure | Security Scanning Agent |
| Deploy & Secure | Environment Configuration |
| Deploy & Secure | Secrets Management |
| Contributing | Roadmap |
| Contributing | Community / Discord |
---
## Pages to Remove from Nav / Condense
| Page | Recommendation |
| ------------------------------------- | -------------------------------------------------------- |
| ☑️ `features/system-notifications` | Fold into Settings or remove |
| ❎ `features/more-features` | Remove |
| ☑️ `features/suggested-responses` | Fold into Chat Interface |
| ☑️ `features/auto-approving-actions` | Fold into Settings |
| ☑️ `advanced-usage/auto-cleanup` | Fold into Settings |
| ❎ `features/model-temperature` | Remove |
| ☑️ `advanced-usage/rate-limits-costs` | Fold into Adding Credits or AI Providers |
| ❎ `features/footgun-prompting` | Remove |
| ☑️ `tips-and-tricks` | Could become a blog post or fold relevant bits elsewhere |
---
## Summary
**Reusable as-is:** ~70% of your content maps cleanly
**Needs new pages:** ~12-15 new pages, mostly for newer cloud/platform features
**Condense/remove:** ~10-12 pages that are either too granular or should be folded into parent pages
**Tools Reference:** Decide if this stays in nav or becomes a "Reference" footer link - it's useful but clutters the IA
Want me to mock up the actual sidebar structure with the subheaders?
+16
View File
@@ -0,0 +1,16 @@
/* Use this file to export your Markdoc functions */
export const includes = {
transform(parameters) {
const [array, value] = Object.values(parameters)
return Array.isArray(array) ? array.includes(value) : false
},
}
export const upper = {
transform(parameters) {
const string = parameters[0]
return typeof string === "string" ? string.toUpperCase() : string
},
}
@@ -0,0 +1,7 @@
import { nodes } from "@markdoc/markdoc"
import { CodeBlock } from "../../components"
export const fence = {
render: CodeBlock,
attributes: nodes.fence.attributes,
}
@@ -0,0 +1,32 @@
import { Tag } from "@markdoc/markdoc"
import { Heading } from "../../components"
function generateID(children, attributes) {
if (attributes.id && typeof attributes.id === "string") {
return attributes.id
}
return children
.filter((child) => typeof child === "string")
.join(" ")
.replace(/[?]/g, "")
.replace(/\s+/g, "-")
.toLowerCase()
}
export const heading = {
render: Heading,
children: ["inline"],
attributes: {
id: { type: String },
level: { type: Number, required: true, default: 1 },
className: { type: String },
},
transform(node, config) {
const attributes = node.transformAttributes(config)
const children = node.transformChildren(config)
const id = generateID(children, attributes)
return new Tag(this.render, { ...attributes, id }, children)
},
}
@@ -0,0 +1,4 @@
/* Use this file to export your markdoc nodes */
export * from "./fence.markdoc"
export * from "./heading.markdoc"
export * from "./table.markdoc"
@@ -0,0 +1,41 @@
import { nodes } from "@markdoc/markdoc"
import { Table, THead, TBody, Tr, Th, Td } from "../../components/Table"
export const table = {
...nodes.table,
render: Table,
}
export const thead = {
...nodes.thead,
render: THead,
}
export const tbody = {
...nodes.tbody,
render: TBody,
}
export const tr = {
...nodes.tr,
render: Tr,
}
export const th = {
...nodes.th,
render: Th,
attributes: {
...nodes.th.attributes,
width: { type: String },
},
}
export const td = {
...nodes.td,
render: Td,
attributes: {
...nodes.td.attributes,
colspan: { type: Number },
rowspan: { type: Number },
},
}
@@ -0,0 +1,13 @@
Use Kilo Code directly from your terminal for maximum flexibility.
### Install via npm
```bash
npm install -g @kilocode/cli
```
### Verify Installation
```bash
kilo --version
```
@@ -0,0 +1,46 @@
Kilo Code supports all JetBrains IDEs including IntelliJ IDEA, WebStorm, PyCharm, and more.
### Prerequisites
Before installing the Kilo Code plugin, ensure you have:
1. **JetBrains Toolbox (Recommended):**
- Download from [https://www.jetbrains.com/toolbox-app/](https://www.jetbrains.com/toolbox-app/)
- Toolbox is required for authentication callbacks to work properly
- Without Toolbox, you'll need to manually configure API keys
2. **Node.js:**
- Download LTS version from [https://nodejs.org/](https://nodejs.org/)
- Required for the extension's backend services
### Install directly
1. If you don't have a JetBrains IDE installed, download one from [jetbrains.com](https://www.jetbrains.com/)
2. Then, you can click the button below to install Kilo Code directly from the JetBrains Marketplace:
[![Install Kilo Code](https://img.shields.io/badge/Install%20Kilo%20Code-F8F674?style=for-the-badge)](https://plugins.jetbrains.com/plugin/28350-kilo-code)
### Install from JetBrains Marketplace
1. Open your JetBrains IDE
2. Go to **Settings/Preferences → Plugins**
3. Click **Marketplace** tab
4. Search for "Kilo Code"
5. Click **Install** and restart your IDE
### Supported IDEs
- IntelliJ IDEA
- WebStorm
- PyCharm
- PhpStorm
- GoLand
- Rider
- CLion
- RubyMine
- DataGrip
{% callout type="info" %}
Both Community and Ultimate editions are supported. Some AI features may vary based on your JetBrains license.
{% /callout %}
@@ -0,0 +1,41 @@
## Other IDEs & Editors
Kilo Code supports additional VS Code-based editors. Since these editors share VS Code's extension architecture, installation follows a similar process.
### Cursor
1. Open Cursor
2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`)
3. Search for "Kilo Code"
4. Click **Install**
### VS Code Insiders
[VS Code Insiders](https://code.visualstudio.com/insiders/) is the pre-release version of VS Code with the latest features.
1. Open VS Code Insiders
2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`)
3. Search for "Kilo Code"
4. Click **Install**
{% callout type="note" %}
Extensions installed in VS Code Insiders are separate from your regular VS Code installation.
{% /callout %}
### Windsurf
1. Open Windsurf
2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`)
3. Search for "Kilo Code"
4. Click **Install**
### Trae AI
1. Open Trae AI
2. Go to Extensions (`Ctrl+Shift+X` / `Cmd+Shift+X`)
3. Search for "Kilo Code"
4. Click **Install**
{% callout type="info" %}
All VS Code-based editors support [VSIX installation](#via-vsix) if the extension isn't available directly in their marketplace.
{% /callout %}
@@ -0,0 +1,21 @@
Bring Kilo Code directly into your team's Slack workspace.
### Install the Slack App
1. Click the button below to install Kilo for Slack
1. Select your workspace
1. Authorize the required permissions
[![Add to Slack](https://platform.slack-edge.com/img/add_to_slack.png)](https://app.kilo.ai/get-started/slack)
{% callout type="info" %}
You'll need app installation permissions to install the Slack app in your workspace.
{% /callout %}
### Usage
Once installed, mention the bot in a channel or send a direct message:
```
@Kilo Can you update the documentation for the new API endpoint in the backend repository?
```
@@ -0,0 +1,23 @@
### Install directly
1. If you don't have VS Code installed, download it from [code.visualstudio.com](https://code.visualstudio.com/)
2. Then, you can click the button below to install Kilo Code directly from the VS Code Marketplace:
[![Install Kilo Code](https://img.shields.io/badge/Install%20Kilo%20Code-F8F674?style=for-the-badge)](vscode:extension/kilocode.kilo-code)
### Install from VS Code Marketplace
1. Open VS Code
2. Press `Ctrl+Shift+X` (Windows/Linux) or `Cmd+Shift+X` (macOS) to open Extensions
3. Search for "Kilo Code"
4. Click **Install**
### Install via Command Line
```bash
code --install-extension kilocode.kilo-code
```
### Verify Installation
After installation, you should see the Kilo Code icon ({% kiloCodeIcon /%}) in the Activity Bar on the left side of VS Code. Click it to open the Kilo Code panel.
@@ -0,0 +1,23 @@
import { Callout } from "../../components"
export const callout = {
render: Callout,
children: ["paragraph", "tag", "list"],
attributes: {
title: {
type: String,
description: "Optional custom title for the callout",
},
type: {
type: String,
default: "note",
matches: ["generic", "note", "tip", "info", "warning", "danger"],
description: "The type of callout: generic (no icon/title), note, tip, info, warning, or danger",
},
collapsed: {
type: Boolean,
default: false,
description: "When true, the callout starts collapsed and can be expanded by clicking the header",
},
},
}
@@ -0,0 +1,23 @@
import { Codicon } from "../../components"
export const codicon = {
render: Codicon,
selfClosing: true,
attributes: {
name: {
type: String,
required: true,
description: "The name of the VS Code codicon (e.g., 'send', 'check', 'warning')",
},
size: {
type: String,
default: "1em",
description: "The size of the icon (CSS font-size value)",
},
className: {
type: String,
default: "",
description: "Additional CSS classes to apply to the icon",
},
},
}
@@ -0,0 +1,24 @@
import { Icon } from "../../components"
export const icon = {
render: Icon,
selfClosing: true,
attributes: {
src: {
type: String,
required: true,
},
srcDark: {
type: String,
description: "Optional image source for dark mode. Falls back to src if not provided.",
},
alt: {
type: String,
default: "icon",
},
size: {
type: String,
default: "1.2em",
},
},
}
@@ -0,0 +1,30 @@
import { Image } from "../../components"
export const image = {
render: Image,
selfClosing: true,
attributes: {
src: {
type: String,
required: true,
description: "The image source URL",
},
alt: {
type: String,
required: true,
description: "Alternative text for the image",
},
width: {
type: String,
description: "Width of the image (e.g., '500px', '80%')",
},
height: {
type: String,
description: "Height of the image (e.g., '300px', 'auto')",
},
caption: {
type: String,
description: "Optional caption displayed below the image",
},
},
}
+8
View File
@@ -0,0 +1,8 @@
/* Use this file to export your markdoc tags */
export * from "./callout.markdoc"
export * from "./codicon.markdoc"
export * from "./tabs.markdoc"
export * from "./icon.markdoc"
export * from "./image.markdoc"
export * from "./kilo-code-icon.markdoc"
export * from "./youtube.markdoc"
@@ -0,0 +1,13 @@
import { KiloCodeIcon } from "../../components"
export const kiloCodeIcon = {
render: KiloCodeIcon,
selfClosing: true,
attributes: {
size: {
type: String,
default: "1.2em",
description: "Size of the icon (CSS height value)",
},
},
}
@@ -0,0 +1,19 @@
import { Tabs, Tab } from "../../components"
export const tabs = {
render: Tabs,
children: ["tab"],
attributes: {},
}
export const tab = {
render: Tab,
children: ["paragraph", "tag", "list", "fence", "heading"],
attributes: {
label: {
type: String,
required: true,
description: "The label shown on the tab button",
},
},
}
@@ -0,0 +1,21 @@
import { YouTube } from "../../components"
export const youtube = {
render: YouTube,
selfClosing: true,
attributes: {
url: {
type: String,
required: true,
description: "The YouTube video URL",
},
title: {
type: String,
description: "Accessible title for the video iframe",
},
caption: {
type: String,
description: "Optional caption to display below the video",
},
},
}
+22
View File
@@ -0,0 +1,22 @@
const withMarkdoc = require("@markdoc/next.js")
const previousDocsRedirects = require("./previous-docs-redirects")
module.exports = withMarkdoc(/* config: https://markdoc.io/docs/nextjs#options */)({
pageExtensions: ["js", "jsx", "ts", "tsx", "md", "mdoc"],
basePath: "/docs",
turbopack: {},
async redirects() {
return [...previousDocsRedirects]
},
async rewrites() {
return {
beforeFiles: [
{
// Rewrite /docs/llms.txt to the API endpoint (internal to basePath)
source: "/llms.txt",
destination: "/api/llms.txt",
},
],
}
},
})
+35
View File
@@ -0,0 +1,35 @@
{
"name": "@kilocode/kilo-docs",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "next dev --webpack --port 3002",
"build": "next build --webpack",
"start": "next start",
"test": "vitest run"
},
"dependencies": {
"@docsearch/css": "^4",
"@docsearch/js": "^4",
"@markdoc/markdoc": "^0.5.4",
"@markdoc/next.js": "^0.5.0",
"js-yaml": "^4.1.0",
"@vscode/codicons": "^0.0.44",
"next": "^16.1.5",
"posthog-js": "^1.335.3",
"prismjs": "^1.30.0",
"react": "^19.2.4",
"react-dom": "^19.2.4"
},
"devDependencies": {
"@tailwindcss/postcss": "^4.1.18",
"@types/node": "^25.0.10",
"@types/react": "^19.2.9",
"@types/react-dom": "^19.2.3",
"autoprefixer": "^10.4.23",
"postcss": "^8.5.6",
"tailwindcss": "^4.1.18",
"typescript": "^5.9.3",
"vitest": "^3.2.3"
}
}
+229
View File
@@ -0,0 +1,229 @@
import React from "react"
import Link from "next/link"
import Head from "next/head"
export default function Custom404() {
return (
<>
<Head>
<title>404 - Page Not Found | Kilo Code Documentation</title>
<meta name="description" content="The requested page could not be found." />
</Head>
<div className="not-found-page">
<div className="not-found-container">
{/* Terminal Window */}
<div className="terminal-window">
<div className="terminal-header">
<div className="terminal-dots">
<span className="dot red"></span>
<span className="dot yellow"></span>
<span className="dot green"></span>
</div>
<span className="terminal-title">terminal</span>
</div>
<div className="terminal-body">
<div className="terminal-line">
<span className="prompt">$</span>
<span className="command"> GET /requested-path</span>
</div>
<div className="terminal-line error">
<span className="error-text">Error 404: Page not found</span>
</div>
<div className="error-code">
<div className="error-bar"></div>
<span className="code-404">404</span>
</div>
</div>
</div>
{/* 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>
</div>
{/* Actions */}
<div className="actions">
<Link href="/" className="btn btn-primary">
Return to Documentation
</Link>
<Link href="/getting-started" className="btn btn-secondary">
Getting Started
</Link>
</div>
</div>
<style jsx>{`
.not-found-page {
min-height: calc(100vh - var(--top-nav-height));
display: flex;
align-items: center;
justify-content: center;
padding: 2rem;
background: var(--bg-color);
}
.not-found-container {
max-width: 600px;
width: 100%;
text-align: center;
}
/* Terminal Window */
.terminal-window {
background: #2d2d2d;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
margin-bottom: 2.5rem;
}
.terminal-header {
background: #3d3d3d;
padding: 0.75rem 1rem;
display: flex;
align-items: center;
gap: 0.75rem;
}
.terminal-dots {
display: flex;
gap: 6px;
}
.dot {
width: 12px;
height: 12px;
border-radius: 50%;
}
.dot.red {
background: #ff5f56;
}
.dot.yellow {
background: #ffbd2e;
}
.dot.green {
background: #27ca40;
}
.terminal-title {
color: #888;
font-family: "JetBrains Mono", monospace;
font-size: 0.85rem;
}
.terminal-body {
padding: 1.5rem;
text-align: left;
}
.terminal-line {
font-family: "JetBrains Mono", monospace;
font-size: 0.95rem;
margin-bottom: 0.5rem;
}
.prompt {
color: #f8f674;
}
.command {
color: #a0a0a0;
}
.terminal-line.error {
margin-top: 0.25rem;
}
.error-text {
color: #ff6b6b;
}
.error-code {
display: flex;
align-items: center;
margin-top: 1rem;
padding-left: 0.5rem;
}
.error-bar {
width: 4px;
height: 80px;
background: #f8f674;
margin-right: 1.5rem;
border-radius: 2px;
}
.code-404 {
font-family: "JetBrains Mono", monospace;
font-size: 4.5rem;
font-weight: 700;
color: #f8f674;
line-height: 1;
}
/* Message Section */
.message-section {
margin-bottom: 2rem;
}
.message-title {
font-family: "JetBrains Mono", monospace;
font-size: 1.5rem;
font-weight: 600;
color: var(--text-header);
margin: 0 0 0.75rem 0;
}
.message-subtitle {
color: var(--text-secondary);
font-size: 1rem;
margin: 0;
line-height: 1.5;
}
/* Actions */
.actions {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
/* Mobile Responsive */
@media (max-width: 600px) {
.not-found-page {
padding: 1.5rem;
}
.code-404 {
font-size: 3.5rem;
}
.error-bar {
height: 60px;
}
.message-title {
font-size: 1.25rem;
}
.actions {
flex-direction: column;
}
.actions :global(.btn) {
width: 100%;
}
}
`}</style>
</div>
</>
)
}
// This tells Next.js to use a different layout approach
Custom404.is404 = true
+272
View File
@@ -0,0 +1,272 @@
import { useState, useEffect } from "react"
import Head from "next/head"
import { useRouter } from "next/router"
import posthog from "posthog-js"
import { CopyPageButton, SideNav, TableOfContents, TopNav } from "../components"
import "prismjs"
import "prismjs/components/prism-bash.min"
import "prismjs/components/prism-javascript.min"
import "prismjs/components/prism-typescript.min"
import "prismjs/components/prism-python.min"
import "prismjs/components/prism-json.min"
import "prismjs/components/prism-yaml.min"
import "prismjs/components/prism-go.min"
import "prismjs/components/prism-ruby.min"
import "prismjs/components/prism-markdown.min"
import "prismjs/components/prism-powershell.min"
import "prismjs/themes/prism.css"
import "@docsearch/css"
import "../public/globals.css"
import type { AppProps } from "next/app"
import type { MarkdocNextJsPageProps } from "@markdoc/next.js"
const TITLE = "Kilo Code Documentation"
const DESCRIPTION = "Build, ship, and iterate faster with the most popular open source coding agent."
function collectHeadings(node, sections = []) {
if (node) {
// Skip headings inside tabs - they're not always visible
if (node.name === "Tabs") {
return sections
}
if (node.name === "Heading") {
const title = node.children[0]
if (typeof title === "string") {
sections.push({
...node.attributes,
title,
})
}
}
if (node.children) {
for (const child of node.children) {
collectHeadings(child, sections)
}
}
}
return sections
}
export type MyAppProps = MarkdocNextJsPageProps
export default function MyApp({ Component, pageProps }: AppProps<MyAppProps>) {
const { markdoc } = pageProps
const router = useRouter()
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
// Check if we're on the homepage or 404 page (full-page layouts)
const isHomepage = router.pathname === "/"
const is404 = router.pathname === "/404"
const isFullPageLayout = isHomepage || is404
// Track initial pageview (routeChangeComplete doesn't fire on first load)
useEffect(() => {
posthog.capture("$pageview")
}, [])
// Close mobile menu on route change and track pageviews
useEffect(() => {
const handleRouteChange = () => {
setIsMobileMenuOpen(false)
}
const handleRouteComplete = () => {
posthog.capture("$pageview")
}
router.events.on("routeChangeStart", handleRouteChange)
router.events.on("routeChangeComplete", handleRouteComplete)
return () => {
router.events.off("routeChangeStart", handleRouteChange)
router.events.off("routeChangeComplete", handleRouteComplete)
}
}, [router])
// Prevent body scroll when mobile menu is open
useEffect(() => {
if (isMobileMenuOpen) {
document.body.style.overflow = "hidden"
} else {
document.body.style.overflow = ""
}
return () => {
document.body.style.overflow = ""
}
}, [isMobileMenuOpen])
const handleMobileMenuToggle = () => {
setIsMobileMenuOpen(!isMobileMenuOpen)
}
const handleMobileMenuClose = () => {
setIsMobileMenuOpen(false)
}
let title = TITLE
let description = DESCRIPTION
if (markdoc) {
if (markdoc.frontmatter.title) {
title = markdoc.frontmatter.title
}
if (markdoc.frontmatter.description) {
description = markdoc.frontmatter.description
}
}
const toc = pageProps.markdoc?.content ? collectHeadings(pageProps.markdoc.content) : []
return (
<>
<Head>
<title>{title}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<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" />
<meta name="theme-color" content="#617A91" />
{/* Preconnect to Algolia for better performance */}
<link rel="preconnect" href="https://PMZUYBQDAK-dsn.algolia.net" crossOrigin="anonymous" />
{/* Script to prevent flash of wrong theme */}
<script
dangerouslySetInnerHTML={{
__html: `
(function() {
try {
var theme = localStorage.getItem('theme');
if (theme === 'dark' || (!theme && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
} catch (e) {}
})();
`,
}}
/>
</Head>
<TopNav
onMobileMenuToggle={handleMobileMenuToggle}
isMobileMenuOpen={isMobileMenuOpen}
showMobileMenuButton={!isFullPageLayout}
/>
{isFullPageLayout ? (
<main className="fullpage-main">
<Component {...pageProps} />
</main>
) : (
<div className="page">
<SideNav isMobileOpen={isMobileMenuOpen} onMobileClose={handleMobileMenuClose} />
<main className="main-content">
<div className="content-wrapper">
<div className="article-content flex column mt-5">
<Component {...pageProps} />
</div>
<div className="right-sidebar">
{markdoc && <CopyPageButton />}
<TableOfContents toc={toc} />
</div>
</div>
</main>
</div>
)}
<style jsx>
{`
.fullpage-main {
position: fixed;
top: var(--top-nav-height);
left: 0;
right: 0;
bottom: 0;
overflow: auto;
background: var(--bg-color);
transition: background-color 0.2s ease;
}
.page {
position: fixed;
top: var(--top-nav-height);
left: 0;
right: 0;
bottom: 0;
display: flex;
overflow: hidden;
}
.main-content {
overflow-y: auto;
overflow-x: hidden;
height: calc(100vh - var(--top-nav-height));
flex: 1 1 0;
min-width: 0;
background: var(--bg-color);
transition: background-color 0.2s ease;
}
.content-wrapper {
display: flex;
position: relative;
max-width: 1200px;
margin: 0 auto;
width: 100%;
padding-right: 1rem;
box-sizing: border-box;
}
.article-content {
flex: 1 1 0;
font-size: 16px;
padding: 0 2rem 2rem;
min-width: 0;
max-width: 100%;
overflow: hidden;
overflow-wrap: break-word;
word-wrap: break-word;
}
.article-content > * {
max-width: 100%;
}
.article-content pre {
max-width: 100%;
overflow-x: auto;
}
.right-sidebar {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 1rem;
padding-top: 2.5rem;
flex: 0 0 240px;
position: sticky;
top: 0;
height: fit-content;
}
/* Mobile responsive styles */
@media (max-width: 1024px) {
.right-sidebar {
display: none;
}
.content-wrapper {
padding-right: 0;
}
}
@media (max-width: 768px) {
.article-content {
padding: 0 1rem 1.5rem;
}
}
`}
</style>
</>
)
}
@@ -0,0 +1,31 @@
---
sidebar_label: Anthropic
---
# Using Anthropic With Kilo Code
Anthropic is an AI safety and research company that builds reliable, interpretable, and steerable AI systems. Their Claude models are known for their strong reasoning abilities, helpfulness, and honesty.
**Website:** [https://www.anthropic.com/](https://www.anthropic.com/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Anthropic Console](https://console.anthropic.com/). Create an account or sign in.
2. **Navigate to API Keys:** Go to the [API keys](https://console.anthropic.com/settings/keys) section.
3. **Create a Key:** Click "Create Key". Give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Anthropic" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Anthropic API key into the "Anthropic API Key" field.
4. **Select Model:** Choose your desired Claude model from the "Model" dropdown.
5. **(Optional) Custom Base URL:** If you need to use a custom base URL for the Anthropic API, check "Use custom base URL" and enter the URL. Most people won't need to adjust this.
## Tips and Notes
- **Prompt Caching:** Claude 3 models support [prompt caching](https://docs.anthropic.com/en/docs/build-with-claude/prompt-caching), which can significantly reduce costs and latency for repeated prompts.
- **Context Window:** Claude models have large context windows (200,000 tokens), allowing you to include a significant amount of code and context in your prompts.
- **Pricing:** Refer to the [Anthropic Pricing](https://www.anthropic.com/pricing) page for the latest pricing information.
- **Rate Limits:** Anthropic has strict rate limits based on [usage tiers](https://docs.anthropic.com/en/api/rate-limits#requirements-to-advance-tier). If you're repeatedly hitting rate limits, consider contacting Anthropic sales or accessing Claude through a different provider like [OpenRouter](/docs/ai-providers/openrouter) or [Requesty](/docs/ai-providers/requesty).
@@ -0,0 +1,55 @@
---
sidebar_label: AWS Bedrock
---
# Using AWS Bedrock With Kilo Code
Kilo Code supports accessing models through Amazon Bedrock, a fully managed service that makes a selection of high-performing foundation models (FMs) from leading AI companies available via a single API. This provider connects directly to AWS Bedrock and authenticates with the provided credentials.
**Website:** [https://aws.amazon.com/bedrock/](https://aws.amazon.com/bedrock/)
## Prerequisites
- **AWS Account:** You need an active AWS account.
- **Bedrock Access:** You must request and be granted access to Amazon Bedrock. See the [AWS Bedrock documentation](https://docs.aws.amazon.com/bedrock/latest/userguide/getting-started.html) for details on requesting access.
- **Model Access:** Within Bedrock, you need to request access to the specific models you want to use (e.g., Anthropic Claude).
- **Install AWS CLI:** Use AWS CLI to configure your account for authentication
```bash
aws configure
```
## Getting Credentials
You have three options for configuring AWS credentials:
1. **Bedrock API Key:**
- Create a Bedrock-specific API key in the AWS Console. This is a simple service-specific authentication method.
- See the [AWS documentation on Bedrock credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_bedrock.html) for instructions on creating an API key.
2. **AWS Access Keys (Recommended for Development):**
- Create an IAM user with the necessary permissions (at least `bedrock:InvokeModel`).
- Generate an access key ID and secret access key for that user.
- _(Optional)_ Create a session token if required by your IAM configuration.
3. **AWS Profile:**
- Configure an AWS profile using the AWS CLI or by manually editing your AWS credentials file. See the [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html) for details.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Bedrock" from the "API Provider" dropdown.
3. **Select Authentication Method:**
- **Bedrock API Key:**
- Enter your Bedrock API key directly. This is the simplest setup option.
- **AWS Credentials:**
- Enter your "AWS Access Key" and "AWS Secret Key."
- (Optional) Enter your "AWS Session Token" if you're using temporary credentials.
- **AWS Profile:**
- Enter your "AWS Profile" name (e.g., "default").
4. **Select Region:** Choose the AWS region where your Bedrock service is available (e.g., "us-east-1").
5. **(Optional) Cross-Region Inference:** Check "Use cross-region inference" if you want to access models in a region different from your configured AWS region.
6. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Permissions:** Ensure your IAM user or role has the necessary permissions to invoke Bedrock models. The `bedrock:InvokeModel` permission is required.
- **Pricing:** Refer to the [Amazon Bedrock pricing](https://aws.amazon.com/bedrock/pricing/) page for details on model costs.
- **Cross-Region Inference:** Using cross-region inference may result in higher latency.
@@ -0,0 +1,30 @@
---
sidebar_label: Cerebras
---
# Using Cerebras With Kilo Code
Cerebras is known for their ultra-fast AI inference powered by the Cerebras CS-3 chip, the world's largest and fastest AI accelerator. Their platform delivers exceptional inference speeds for large language models, making them ideal for interactive development workflows.
**Website:** [https://cerebras.ai/](https://cerebras.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Cerebras Cloud Platform](https://cloud.cerebras.ai/). Create an account or sign in.
2. **Navigate to API Keys:** Access the API Keys section in your account dashboard.
3. **Create a Key:** Click to generate a new API key. Give it a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Cerebras" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Cerebras API key into the "Cerebras API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Inference Speed:** Cerebras models deliver some of the fastest inference speeds available, reducing wait times during development.
- **Open Source Models:** Many Cerebras models are based on open-source architectures, optimized for their custom hardware.
- **Cost Efficiency:** Fast inference can lead to better cost efficiency for interactive use cases.
- **Pricing:** Refer to the Cerebras platform for current pricing information and available plans.
@@ -0,0 +1,32 @@
---
sidebar_label: Chutes AI
---
# Using Chutes AI With Kilo Code
Chutes.ai offers free API access to several large language models (LLMs), allowing developers to integrate and experiment with these models without immediate financial commitment. They provide access to a curated set of open-source and proprietary language models, often with a focus on specific capabilities or regional language support.
**Website:** [https://chutes.ai/](https://chutes.ai/)
## Getting an API Key
To use Chutes AI with Kilo Code, obtain an API key from the [Chutes AI platform](https://chutes.ai/). After signing up or logging in, you should find an option to generate or retrieve your API key within your account dashboard or settings.
## Supported Models
Kilo Code will attempt to fetch the list of available models from the Chutes AI API. The specific models available will depend on Chutes AI's current offerings.
Always refer to the official Chutes AI documentation or your dashboard for the most up-to-date list of supported models.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Chutes AI" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Chutes AI API key into the "Chutes AI API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Free Access:** Chutes AI provides free API access, making it an excellent option for experimentation and development without immediate costs.
- **Model Variety:** The platform offers access to both open-source and proprietary models, giving you flexibility in choosing the right model for your needs.
- **Rate Limits:** As with any free service, be aware of potential rate limits or usage restrictions that may apply to your API key.
@@ -0,0 +1,56 @@
---
sidebar_label: Claude Code
---
{% callout type="warning" title="Important Notice" %}
In January 2026, Anthropic decided to restrict Claude Code CLI to official Claude Code clients. Claude Code credentials cannot be used in Kilo Code or other third-party harnesses.
For continued use of Anthropic models in Kilo Code, please use the [Anthropic API provider](/docs/ai-providers/anthropic) with an API key instead.
{% /callout %}
# Using Claude Code With Kilo Code
Claude Code is Anthropic's official CLI that provides direct access to Claude models from your terminal. Using Claude Code with Kilo Code lets you leverage your existing CLI setup without needing separate API keys.
**Website:** [https://docs.anthropic.com/en/docs/claude-code/setup](https://docs.anthropic.com/en/docs/claude-code/setup)
## Installing and Setting Up Claude Code
1. **Install Claude Code:** Follow the installation instructions at [Anthropic's Claude Code documentation](https://docs.anthropic.com/en/docs/claude-code/setup).
2. **Authenticate:** Run `claude` in your terminal. Claude Code offers multiple authentication options including the Anthropic Console (default), Claude App with Pro/Max plans, and enterprise platforms like Amazon Bedrock or Google Vertex AI. See [Anthropic's authentication documentation](https://docs.anthropic.com/en/docs/claude-code/setup) for complete details.
3. **Verify Installation:** Test that everything works by running `claude --version` in your terminal.
{% callout type="warning" title="Environment Variable Usage" %}
The `claude` command-line tool, like other Anthropic SDKs, can use the `ANTHROPIC_API_KEY` environment variable for authentication. This is a common method for authorizing CLI tools in non-interactive environments.
If this environment variable is set on your system, the `claude` tool may use it for authentication instead of the interactive `/login` method. When Kilo Code executes the tool, it will accurately reflect that an API key is being used, as this is the underlying behavior of the `claude` CLI itself.
{% /callout %}
**Website:** [https://docs.anthropic.com/en/docs/claude-code/setup](https://docs.anthropic.com/en/docs/claude-code/setup)
## Supported Models
The specific models available depend on your Claude subscription and plan. See [Anthropic's Model Documentation](https://docs.anthropic.com/en/docs/about-claude/models) for more details on each model's capabilities.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Claude Code" from the "API Provider" dropdown.
3. **Select Model:** Choose your desired Claude model from the "Model" dropdown.
4. **(Optional) Custom CLI Path:** If you installed Claude Code to a location other than the default `claude` command, enter the full path to your Claude executable in the "Claude Code Path" field. Most users won't need to change this.
## Tips and Notes
- **No API Keys Required:** Claude Code uses your existing CLI authentication, so you don't need to manage separate API keys.
- **Cost Transparency:** Usage costs are reported directly by the Claude CLI, giving you clear visibility into your spending.
- **Advanced Reasoning:** Full support for Claude's thinking modes and reasoning capabilities when available.
- **Context Windows:** Claude models have large context windows, allowing you to include significant amounts of code and context in your prompts.
- **Enhance Prompt Feature:** Full compatibility with Kilo Code's Enhance Prompt feature, allowing you to automatically improve and refine your prompts before sending them to Claude.
- **Custom Paths:** If you installed Claude Code in a non-standard location, you can specify the full path in the settings. Examples:
- Windows: `C:\tools\claude\claude.exe`
- macOS/Linux: `/usr/local/bin/claude` or `~/bin/claude`
## Troubleshooting
- **"Claude Code process exited with error":** Verify Claude Code is installed (`claude --version`) and authenticated (`claude auth login`). Make sure your subscription includes the selected model.
- **Custom path not working:** Use the full absolute path to the Claude executable and verify the file exists and is executable. On Windows, include the `.exe` extension.
@@ -0,0 +1,27 @@
---
sidebar_label: DeepSeek
---
# Using DeepSeek With Kilo Code
Kilo Code supports accessing models through the DeepSeek API, including `deepseek-chat` and `deepseek-reasoner`.
**Website:** [https://platform.deepseek.com/](https://platform.deepseek.com/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [DeepSeek Platform](https://platform.deepseek.com/). Create an account or sign in.
2. **Navigate to API Keys:** Find your API keys in the [API keys](https://platform.deepseek.com/api_keys) section of the platform.
3. **Create a Key:** Click "Create new API key". Give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "DeepSeek" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your DeepSeek API key into the "DeepSeek API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Pricing:** Refer to the [DeepSeek Pricing](https://api-docs.deepseek.com/quick_start/pricing/) page for details on model costs.
@@ -0,0 +1,29 @@
---
title: Fireworks AI with Kilo Code
---
# Using Fireworks AI With Kilo Code
Fireworks AI is a high-performance platform for running AI models that offers fast access to a wide range of open-source and proprietary language models. Built for speed and reliability, Fireworks AI provides both serverless and dedicated deployment options with OpenAI-compatible APIs.
**Website:** [https://fireworks.ai/](https://fireworks.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to [Fireworks AI](https://fireworks.ai/) and create an account or sign in.
2. **Navigate to API Keys:** After logging in, go to the [API Keys page](https://app.fireworks.ai/settings/users/api-keys) in the account settings.
3. **Create a Key:** Click "Create API key" and give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** Copy the API key _immediately_ and store it securely. You will not be able to see it again.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Fireworks AI" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Fireworks AI API key into the "Fireworks AI API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Performance:** Fireworks AI is optimized for speed and offers excellent performance for both chat and completion tasks.
- **Pricing:** Refer to the [Fireworks AI Pricing](https://fireworks.ai/pricing) page for current pricing information.
- **Rate Limits:** Fireworks AI has usage-based rate limits. Monitor your usage in the dashboard and consider upgrading your plan if needed.
@@ -0,0 +1,28 @@
---
sidebar_label: Google Gemini
---
# Using Google Gemini With Kilo Code
Kilo Code supports Google's Gemini family of models through the Google AI Gemini API.
**Website:** [https://ai.google.dev/](https://ai.google.dev/)
## Getting an API Key
1. **Go to Google AI Studio:** Navigate to [https://ai.google.dev/](https://ai.google.dev/).
2. **Sign In:** Sign in with your Google account.
3. **Create API Key:** Click on "Create API key" in the left-hand menu.
4. **Copy API Key:** Copy the generated API key.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Google Gemini" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Gemini API key into the "Gemini API Key" field.
4. **Select Model:** Choose your desired Gemini model from the "Model" dropdown.
## Tips and Notes
- **Pricing:** Gemini API usage is priced based on input and output tokens. Refer to the [Gemini pricing page](https://ai.google.dev/pricing) for detailed information.
- **Codebase Indexing:** The `gemini-embedding-001` model is specifically supported for [codebase indexing](/docs/features/codebase-indexing), providing high-quality embeddings for semantic code search.
@@ -0,0 +1,37 @@
---
sidebar_label: Glama
---
# Using Glama With Kilo Code
Glama provides access to a variety of language models through a unified API, including models from Anthropic, OpenAI, and others. It offers features like prompt caching and cost tracking.
**Website:** [https://glama.ai/](https://glama.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Glama sign-up page](https://glama.ai/sign-up). Sign up using your Google account or name/email/password.
2. **Get API Key:** After signing up, navigate to the [API Keys](https://glama.ai/settings/gateway/api-keys) page to get an API key.
3. **Copy the Key:** Copy the displayed API key.
## Supported Models
Kilo Code will automatically try to fetch a list of available models from the Glama API. Some models that are commonly available through Glama include:
- **Anthropic Claude models:** (e.g., `anthropic/claude-3-5-sonnet`) These are generally recommended for best performance with Kilo Code.
- **OpenAI models:** (e.g., `openai/o3-mini-high`)
- **Other providers and open-source models**
Refer to the [Glama documentation](https://glama.ai/models) for the most up-to-date list of supported models.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Glama" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Glama API key into the "Glama API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Pricing:** Glama operates on a pay-per-use basis. Pricing varies depending on the model you choose.
- **Prompt Caching:** Glama supports prompt caching, which can significantly reduce costs and improve performance for repeated prompts.
@@ -0,0 +1,86 @@
---
sidebar_label: Groq
---
# Using Groq With Kilo Code
Groq provides ultra-fast inference for various AI models through their high-performance infrastructure. Kilo Code supports accessing models through the Groq API.
**Website:** [https://groq.com/](https://groq.com/)
## Getting an API Key
To use Groq with Kilo Code, you'll need an API key from the [GroqCloud Console](https://console.groq.com/). After signing up or logging in, navigate to the API Keys section of your dashboard to create and copy your key.
## Supported Models
Kilo Code will attempt to fetch the list of available models from the Groq API.
**Note:** Model availability and specifications may change. Refer to the [Groq Documentation](https://console.groq.com/docs/models) for the most up-to-date list of supported models and their capabilities.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Groq" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Groq API key into the "Groq API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **High-Speed Inference:** Groq's LPUs provide exceptionally fast response times, making it ideal for interactive development workflows.
- **Token Limits:** Some models have specific `max_tokens` limits that are automatically handled by Kilo Code (e.g., the `moonshotai/kimi-k2-instruct` model).
- **Cost Efficiency:** Groq often provides competitive pricing for high-speed inference compared to other providers.
- **Model Selection:** Choose models based on your specific needs - larger models like `llama3-70b-8192` for complex reasoning tasks, or smaller models like `llama3-8b-8192` for faster, simpler operations.
## Supported Models
Kilo Code supports the following models through Groq:
| Model ID | Provider | Context Window | Notes |
| ----------------------------- | ----------- | -------------- | ------------------------------------- |
| `moonshotai/kimi-k2-instruct` | Moonshot AI | 128K tokens | Optimized max_tokens limit configured |
| `llama-3.3-70b-versatile` | Meta | 128K tokens | High-performance Llama model |
| `llama-3.1-70b-versatile` | Meta | 128K tokens | Versatile reasoning capabilities |
| `llama-3.1-8b-instant` | Meta | 128K tokens | Fast inference for quick tasks |
| `mixtral-8x7b-32768` | Mistral AI | 32K tokens | Mixture of experts architecture |
**Note:** Model availability may change. Refer to the [Groq documentation](https://console.groq.com/docs/models) for the latest model list and specifications.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Groq" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Groq API key into the "Groq API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Model-Specific Features
### Kimi K2 Model
The `moonshotai/kimi-k2-instruct` model includes optimized configuration:
- **Max Tokens Limit:** Automatically configured with appropriate limits for optimal performance
- **Context Understanding:** Excellent for complex reasoning and long-context tasks
- **Multilingual Support:** Strong performance across multiple languages
## Tips and Notes
- **Ultra-Fast Inference:** Groq's hardware acceleration provides exceptionally fast response times
- **Cost-Effective:** Competitive pricing for high-performance inference
- **Rate Limits:** Be aware of API rate limits based on your Groq plan
- **Model Selection:** Choose models based on your specific use case:
- **Kimi K2**: Best for complex reasoning and multilingual tasks
- **Llama 3.3 70B**: Excellent general-purpose performance
- **Llama 3.1 8B Instant**: Fastest responses for simple tasks
- **Mixtral**: Good balance of performance and efficiency
## Troubleshooting
- **"Invalid API Key":** Verify your API key is correct and active in the Groq Console
- **"Model Not Available":** Check if the selected model is available in your region
- **Rate Limit Errors:** Monitor your usage in the Groq Console and consider upgrading your plan
- **Connection Issues:** Ensure you have a stable internet connection and Groq services are operational
## Pricing
Groq offers competitive pricing based on input and output tokens. Visit the [Groq pricing page](https://groq.com/pricing/) for current rates and plan options.
@@ -0,0 +1,29 @@
# Human Relay Provider
The Human Relay provider allows you to use Kilo Code with web-based AI models like ChatGPT or Claude without needing an API key. Instead, it relies on you to manually relay messages between Kilo Code and the AI's web interface.
## How it Works
1. **Select Human Relay**: Choose "Human Relay" as your API provider in Kilo Code's settings. No API key is required.
2. **Initiate a Request**: Start a chat or task with Kilo Code as usual.
3. **Dialog Prompt**: A dialog box will appear in VS Code. Your message to the AI is automatically copied to your clipboard.
4. **Paste to Web AI**: Go to the web interface of your chosen AI (e.g., chat.openai.com, claude.ai) and paste the message from your clipboard into the chat input.
5. **Copy AI Response**: Once the AI responds, copy its complete response text.
6. **Paste Back to Kilo Code**: Return to the dialog box in VS Code, paste the AI's response into the designated field, and click "Confirm".
7. **Continue**: Kilo Code will process the response as if it came directly from an API.
## Use Cases
This provider is useful if:
- You want to use models that don't offer direct API access.
- You prefer not to manage API keys.
- You need to leverage the specific capabilities or context available only in the web UI of certain AI models.
## Limitations
- **Manual Effort**: Requires constant copy-pasting between VS Code and your browser.
- **Slower Interaction**: The back-and-forth process is significantly slower than direct API integration.
- **Potential for Errors**: Manual copying and pasting can introduce errors or omissions.
Choose this provider when the benefits of using a specific web AI outweigh the inconvenience of the manual relay process.
@@ -0,0 +1,36 @@
---
sidebar_label: Inception
---
# Using Inception With Kilo Code
Inception provides access to cutting-edge AI models with a focus on performance and reliability. Their infrastructure is designed for enterprise-grade applications requiring consistent, high-quality outputs.
**Website:** [https://www.inceptionlabs.ai](https://www.inceptionlabs.ai)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Inception website](https://www.inceptionlabs.ai) and access their developer/API dashboard.
2. **Navigate to API Keys:** Access the API Keys section in your account settings.
3. **Create a Key:** Click "Create new API key". Give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely.
## Supported Models
Kilo Code supports Inception's available models. Model selection and capabilities may vary based on your account tier.
Refer to Inception's current website and developer documentation for the most up-to-date list of supported models and capabilities.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Inception" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Inception API key into the "Inception API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Enterprise Focus:** Inception is designed for production-grade AI applications with emphasis on reliability and consistency.
- **Pricing:** Refer to the Inception platform for current pricing details and available subscription options.
- **Support:** Enterprise customers have access to dedicated support channels for technical assistance.
- **Docs Feedback:** Report documentation issues at [Kilo-Org/kilocode issues](https://github.com/Kilo-Org/kilocode/issues/new?title=Documentation%20Issue:%20/docs/ai-providers/inception).
@@ -0,0 +1,68 @@
---
title: "AI Providers"
description: "Configure and connect different AI model providers to Kilo Code"
---
# AI Providers
Kilo Code supports a wide variety of AI providers, giving you flexibility in how you power your AI-assisted development workflow. Choose from cloud providers, local models, or AI gateways based on your needs.
## Getting Started
The fastest way to get started is with **Kilo Code's built-in provider**, which requires no configuration. Simply sign in and start coding.
For users who want to use their own API keys or need specific models, we support over 30 providers.
## Provider Categories
### Cloud Providers
Major AI companies offering powerful models via API:
- **[Anthropic](/docs/ai-providers/anthropic)** - Claude models (Claude 4, Claude 3.5 Sonnet, etc.)
- **[OpenAI](/docs/ai-providers/openai)** - GPT-4, GPT-4o, o1, and more
- **[Google Gemini](/docs/ai-providers/gemini)** - Gemini Pro, Gemini Ultra
- **[DeepSeek](/docs/ai-providers/deepseek)** - DeepSeek V3., R1
- **[Mistral](/docs/ai-providers/mistral)** - Mistral Large, Codestral
### Local & Self-Hosted
Run models on your own hardware for privacy and offline use:
- **[Ollama](/docs/ai-providers/ollama)** - Easy local model management
- **[LM Studio](/docs/ai-providers/lmstudio)** - Desktop app for local models
- **[OpenAI Compatible](/docs/ai-providers/openai-compatible)** - Any OpenAI-compatible endpoint
### AI Gateways
Route requests through unified APIs with additional features:
- **[OpenRouter](/docs/ai-providers/openrouter)** - Access multiple providers through one API
- **[Glama](/docs/ai-providers/glama)** - Enterprise AI gateway
- **[Requesty](/docs/ai-providers/requesty)** - Smart routing and fallbacks
## Choosing a Provider
| Priority | Recommended Provider |
| --------------- | --------------------------------------------------- |
| Ease of use | [Kilo Code (built-in)](/docs/ai-providers/kilocode) |
| Best value | Zhipu AI or Mistral |
| Privacy/Offline | Ollama or LM Studio |
| Enterprise | AWS Bedrock or Google Vertex |
## Why Use Multiple Providers?
- **Cost** - Compare pricing across providers for different tasks
- **Reliability** - Backup options when a provider has outages
- **Models** - Access exclusive or specialized models
- **Regional** - Better latency in certain locations
{% callout type="note" %}
All API keys use VS Code's Secret Storage—never stored in plain text.
{% /callout %}
## Next Steps
- **New to Kilo Code?** Start with the [Kilo Code provider](/docs/ai-providers/kilocode) - no setup required
- **Have an API key?** Jump to your provider's page for configuration instructions
- **Want to compare?** Check out [Model Selection](/docs/code-with-ai/agents/model-selection) for guidance on choosing models
@@ -0,0 +1,73 @@
---
sidebar_label: Kilo Code Provider
---
# Using Kilo Code's Built-in Provider
Kilo Code provides its own built-in API provider that gives you access to the latest frontier coding models through a simple registration process. No need to manage API keys from multiple providers - just sign up and start coding.
**Website:** [https://kilo.ai/](https://kilo.ai/)
## Getting Started
When you sign up for Kilo Code, you can start immediately with free models, or top up your account for the first time to get bonus credits.
To claim your bonus credits:
1. **Sign up:** Complete the registration process
2. **First top-up:** Add funds to your account and get $20 bonus credits
3. **Start Coding:** Enjoy your $20 in free credits
## Registration Process
Kilo Code offers a streamlined registration that connects you directly to frontier coding models:
1. **Start Registration:** Click "Try Kilo Code for Free" in the extension
2. **Sign In:** Use your Google account to sign in at kilo.ai
3. **Authorize VS Code:**
- kilo.ai will prompt you to open Visual Studio Code
- For web-based IDEs, you'll copy the API key manually instead
4. **Complete Setup:** Allow VS Code to open the authorization URL when prompted
<!-- <img src="/img/setting-up/signupflow.gif" alt="Sign up and registration flow with Kilo Code" width="600" /> -->
## Supported Models
Kilo Code provides access to the latest frontier coding models through its built-in provider. The specific models available are automatically updated and managed by the Kilo Code service, ensuring you always have access to the most capable models for coding tasks.
## Kilo Gateway integration
Kilo Code routes requests through the Kilo Gateway for model access, usage tracking, and organization controls. For BYOK setup, provider routing, and full model availability, use the Gateway docs as the source of truth:
- [Kilo Gateway overview](/docs/gateway)
- [Models & Providers](/docs/gateway/models-and-providers)
- [Authentication & BYOK](/docs/gateway/authentication)
## Configuration in Kilo Code
Once you've completed the registration process, Kilo Code is automatically configured:
1. **Automatic Setup:** After successful registration, Kilo Code is ready to use immediately
2. **No API Key Management:** Your authentication is handled seamlessly through the registration process
3. **Model Selection:** Access to frontier models is provided automatically through your Kilo Code account
## Connected Accounts
With the Kilo Code provider, if you sign up with Google you can also connect other sign in accounts - like GitHub - by:
1. Go to your profile
2. Select [**Connected Accounts**](https://app.kilo.ai/connected-accounts)
3. Under "Link a New account" select the type of account to link
4. Complete the OAuth authorization, and you'll see your connected accounts!
<!-- <img src="/docs/img/kilo-provider/connected-accounts.png" alt="Connect account screen" width="600" /> -->
## Tips and Notes
- **Free Credits:** New users receive free credits to explore Kilo Code's capabilities
- **Identity Verification:** The temporary hold system ensures service reliability while preventing misuse
- **Seamless Integration:** No need to manage multiple API keys or provider configurations
- **Latest Models:** Automatic access to the most current frontier coding models
- **Support Available:** Contact [hi@kilo.ai](mailto:hi@kilo.ai) for questions about pricing or tokens
For detailed setup instructions, see [Setting up Kilo Code](/docs/getting-started/setting-up).
@@ -0,0 +1,43 @@
---
sidebar_label: LM Studio
---
# Using LM Studio With Kilo Code
Kilo Code supports running models locally using LM Studio. LM Studio provides a user-friendly interface for downloading, configuring, and running local language models. It also includes a built-in local inference server that emulates the OpenAI API, making it easy to integrate with Kilo Code.
**Website:** [https://lmstudio.ai/](https://lmstudio.ai/)
## Setting Up LM Studio
1. **Download and Install LM Studio:** Download LM Studio from the [LM Studio website](https://lmstudio.ai/).
2. **Download a Model:** Use the LM Studio interface to search for and download a model. Some recommended models include:
- CodeLlama models (e.g., `codellama:7b-code`, `codellama:13b-code`, `codellama:34b-code`)
- Mistral models (e.g., `mistralai/Mistral-7B-Instruct-v0.1`)
- DeepSeek Coder models (e.g., `deepseek-coder:6.7b-base`)
- Any other model that is supported by Kilo Code, or for which you can set the context window.
Look for models in the GGUF format. LM Studio provides a search interface to find and download models.
3. **Start the Local Server:**
- Open LM Studio.
- Click the **"Local Server"** tab (the icon looks like `<->`).
- Select the model you downloaded.
- Click **"Start Server"**.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "LM Studio" from the "API Provider" dropdown.
3. **Enter Model ID:** Enter the _file name_ of the model you loaded in LM Studio (e.g., `codellama-7b.Q4_0.gguf`). You can find this in the LM Studio "Local Server" tab.
4. **(Optional) Base URL:** By default, Kilo Code will connect to LM Studio at `http://localhost:1234`. If you've configured LM Studio to use a different address or port, enter the full URL here.
5. **(Optional) Timeout:** By default, API requests time out after 10 minutes. Local models can be slow, if you hit this timeout you can consider increasing it here: VS Code Extensions panel > Kilo Code gear menu > Settings > API Request Timeout.
## Tips and Notes
- **Resource Requirements:** Running large language models locally can be resource-intensive. Make sure your computer meets the minimum requirements for the model you choose.
- **Model Selection:** LM Studio provides a wide range of models. Experiment to find the one that best suits your needs.
- **Local Server:** The LM Studio local server must be running for Kilo Code to connect to it.
- **LM Studio Documentation:** Refer to the [LM Studio documentation](https://lmstudio.ai/docs) for more information.
- **Troubleshooting:** If you see a "Please check the LM Studio developer logs to debug what went wrong" error, you may need to adjust the context length settings in LM Studio.
@@ -0,0 +1,30 @@
---
sidebar_label: MiniMax
---
# Using MiniMax With Kilo Code
MiniMax is a global AI foundation model company focused on fast, cost-efficient multimodal models with strong coding, tool-use, and agentic capabilities. Their flagship MiniMax M2.1 model delivers high-speed inference, long-context reasoning, and advanced development workflow support.
**Website:** [https://www.minimax.io/](https://www.minimax.io/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [MiniMax Console](https://platform.minimax.io/). Create an account or sign in.
2. **Open the API Keys Page:** Navigate to your **Profile > API Keys**.
3. **Create a Key:** Click to generate a new API key and give it a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** Copy the key immediately. You may not be able to view it again. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Navigate to **Providers**. Choose **MiniMax** from the API Provider dropdown.
3. **Enter API Key:** Paste your MiniMax API key into the MiniMax API Key field.
4. **Select Model:** Choose your desired MiniMax model from the Model dropdown.
## Tips and Notes
- **Performance:** MiniMax M2.1 emphasizes fast inference, strong coding ability, and exceptional tool-calling performance.
- **Context Window:** MiniMax models support ultra-long context windows suitable for large codebases and agent workflows.
- **Pricing:** Pricing varies by model, with input costs ranging from $0.20 to $0.30 per million tokens and output costs from $1.10 to $2.20 per million tokens. Refer to the MiniMax documentation for the most current pricing information.
- **MiniMax M2.1** is currently available for free exclusively for [Kilo for Slack](/docs/slack).
@@ -0,0 +1,35 @@
---
sidebar_label: Mistral AI
---
# Using Mistral AI With Kilo Code
Kilo Code supports accessing models through the Mistral AI API, including both standard Mistral models and the code-specialized Codestral model.
**Website:** [https://mistral.ai/](https://mistral.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Mistral Platform](https://console.mistral.ai/). Create an account or sign in. You may need to go through a verification process.
2. **Create an API Key:**
- [La Plateforme API Key](https://console.mistral.ai/api-keys/) and/or
- [Codestral API Key](https://console.mistral.ai/codestral)
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Mistral" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Mistral API key into the "Mistral API Key" field if you're using a `mistral` model. If you intend to use `codestral-latest`, see the "Codestral" section below.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Using Codestral
[Codestral](https://docs.mistral.ai/capabilities/code_generation/) is a model specifically designed for code generation and interaction.
Only for Codestral you could use different endpoints (Default: codestral.mistral.ai).
For the La Platforme API Key change the **Codestral Base Url** to: https://api.mistral.ai
To use Codestral:
1. **Select "Mistral" as the API Provider.**
2. **Select a Codestral Model**
3. **Enter your Codestral (codestral.mistral.ai) or La Plateforme (api.mistral.ai) API Key.**
@@ -0,0 +1,30 @@
---
sidebar_label: Moonshot.ai
---
# Using Moonshot.ai With Kilo Code
Moonshot.ai is a Chinese AI company known for their **Kimi** models featuring ultra-long context windows (up to 200K tokens) and advanced reasoning capabilities. Their K2-Thinking model delivers extended thinking and problem-solving abilities.
**Website:** [https://www.moonshot.cn/](https://www.moonshot.cn/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Moonshot.ai Platform](https://platform.moonshot.cn/). Create an account or sign in.
2. **Navigate to API Keys:** Access the API Keys section in your account dashboard.
3. **Create a Key:** Click to generate a new API key. Give it a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Moonshot.ai" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Moonshot.ai API key into the "Moonshot.ai API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Ultra-Long Context:** Kimi models excel at handling large codebases and complex projects with their extended context windows.
- **Reasoning Capabilities:** The K2-Thinking variant provides enhanced problem-solving through extended reasoning chains.
- **Language Support:** Kimi models have strong support for both English and Chinese languages.
- **Pricing:** Refer to the Moonshot.ai platform for current pricing information on different models.
@@ -0,0 +1,83 @@
---
sidebar_label: Ollama
---
# Using Ollama With Kilo Code
Kilo Code supports running models locally using Ollama. This provides privacy, offline access, and potentially lower costs, but requires more setup and a powerful computer.
**Website:** [https://ollama.com/](https://ollama.com/)
<!-- <image src="/docs/img/providers/ollama-devstral-snake.png" alt="Vibe coding a Snake game using devstral" width="500" />
*Vibe coding a Snake game using devstral* -->
## Managing Expectations
The LLMs that can be run locally are generally much smaller than cloud-hosted LLMs such as Claude and GPT and the results will be much less impressive.
They are much more likely to get stuck in loops, fail to use tools properly or produce syntax errors in code.
More trial and error will be required to find the right prompt.
Running LLMs locally is often also not very fast.
Using simple prompts, keeping conversations short and disabling MCP tools can result in a speed-up.
## Hardware Requirements
You will need a GPU with a large amount of VRAM (24GB or more) or a MacBook with a large amount of unified RAM (32GB or more) to run the models discussed below at decent speed.
## Selecting a Model
Ollama supports many different models.
You can find a list of available models on the [Ollama website](https://ollama.com/library).
For the Kilo Code agent the current recommendation is `qwen3-coder:30b`. `qwen3-coder:30b` sometimes fails to call tools correctly (it is much more likely to have this problem than the full `qwen3-coder:480b` model). As a mixture-of-experts model, this could be because it activated the wrong experts. Whenever this happens, try changing your prompt or use the Enhance Prompt button.
An alternative to `qwen3-coder:30b` is `devstral:24b`. For other features of Kilo Code such as Enhance Prompt or Commit Message Generation smaller models may suffice.
## Setting up Ollama
To set up Ollama for use with Kilo Code, follow the instructions below.
### Download and Install Ollama
Download the Ollama installer from the [Ollama website](https://ollama.com/) (or use the package manager for your operating system). Follow the installation instructions, then make sure Ollama is running:
```bash
ollama serve
```
### Download a Model
To download a model, open a second terminal (`ollama serve` needs to be running) and run:
```bash
ollama pull <model_name>
```
For example:
```bash
ollama pull qwen3-coder:30b
```
### Configure the Context Size
By default Ollama truncates prompts to a very short length, [as documented here](https://github.com/ollama/ollama/blob/4383a3ab7a075eff78b31f7dc84c747e2fcd22b8/docs/faq.md#how-can-i-specify-the-context-window-size).
You need to have at least 32k to get decent results, but increasing the context size increases memory usage and may decrease performance, depending on your hardware.
To configure the context window, set "Context Window Size (num_ctx)" in the API Provider settings.
### Configure the Timout
By default, API requests time out after 10 minutes. Local models can be slow, if you hit this timeout you can consider increasing it here: VS Code Extensions panel > Kilo Code gear menu > Settings > API Request Timeout.
### Configure Kilo Code
- Open the Kilo Code panel ({% kiloCodeIcon size="1em" /%}).
- Click the Settings gear icon ({% codicon name="gear" /%}).
- Select "Ollama" as the API Provider.
- Select the model configured in the previous step.
- (Optional) You can configure the base URL if you're running Ollama on a different machine. The default is `http://localhost:11434`.
## Further Reading
Refer to the [Ollama documentation](https://ollama.com/docs) for more information on installing, configuring and using Ollama.
@@ -0,0 +1,24 @@
---
sidebar_label: ChatGPT Plus/Pro
---
# Using ChatGPT Subscriptions With Kilo Code
1. Open Kilo Code settings (click the gear icon {% codicon name="gear" /%} in the Kilo Code panel).
2. In **API Provider**, select **OpenAI ChatGPT Plus/Pro**.
3. Click **Sign in to OpenAI Codex**.
4. Finish the sign-in flow in your browser.
5. Back in Kilo Code settings, pick a model from the dropdown.
6. Save.
## Tips and Notes
- **Subscription Required:** You need an active ChatGPT Plus or Pro subscription. This provider won't work with free ChatGPT accounts. See [OpenAI's ChatGPT plans](https://openai.com/chatgpt/pricing) for more information.
- **Authentication Errors:** If you receive a CSRF or other error when completing OAuth authentication, ensure you do not have another application already listening on port 1455. You can check on Linux and Mac by using `lsof -i :1455`.
- **No API Costs:** Usage through this provider counts against your ChatGPT subscription, not separately billed API usage.
- **Sign Out:** To disconnect, use the "Sign Out" button in the provider settings.
## Limitations
- **You can't use arbitrary OpenAI API models.** This provider only exposes the models listed in Kilo Code's Codex model catalog.
- **You can't export/migrate your sign-in state with settings export.** OAuth tokens are stored in VS Code SecretStorage, which isn't included in Kilo Code's settings export.
@@ -0,0 +1,70 @@
---
sidebar_label: OpenAI Compatible
---
# Using OpenAI Compatible Providers With Kilo Code
Kilo Code supports a wide range of AI model providers that offer APIs compatible with the OpenAI API standard. This means you can use models from providers _other than_ OpenAI, while still using a familiar API interface. This includes providers like:
- **Local models** running through tools like Ollama and LM Studio (covered in separate sections).
- **Cloud providers** like Perplexity, Together AI, Anyscale, and others.
- **Any other provider** offering an OpenAI-compatible API endpoint.
This document focuses on setting up providers _other than_ the official OpenAI API (which has its own [dedicated configuration page](/docs/ai-providers/openai)).
## General Configuration
The key to using an OpenAI-compatible provider is to configure two main settings:
1. **Base URL:** This is the API endpoint for the provider. It will _not_ be `https://api.openai.com/v1` (that's for the official OpenAI API).
2. **API Key:** This is the secret key you obtain from the provider.
3. **Model ID:** This is the model name of the specific model.
You'll find these settings in the Kilo Code settings panel (click the {% codicon name="gear" /%} icon):
- **API Provider:** Select "OpenAI Compatible".
- **Base URL:** Enter the base URL provided by your chosen provider. **This is crucial.**
- **API Key:** Enter your API key.
- **Model:** Choose a model.
- **Model Configuration:** This lets you customize advanced configuration for the model
- Max Output Tokens
- Context Window
- Image Support
- Computer Use
- Input Price
- Output Price
### Full Endpoint URL Support
Kilo Code supports full endpoint URLs in the Base URL field, providing greater flexibility for provider configuration:
**Standard Base URL Format:**
```
https://api.provider.com/v1
```
**Full Endpoint URL Format:**
```
https://api.provider.com/v1/chat/completions
https://custom-endpoint.provider.com/api/v2/models/chat
```
This enhancement allows you to:
- Connect to providers with non-standard endpoint structures
- Use custom API gateways or proxy services
- Work with providers that require specific endpoint paths
- Integrate with enterprise or self-hosted API deployments
**Note:** When using full endpoint URLs, ensure the URL points to the correct chat completions endpoint for your provider.
## Troubleshooting
- **"Invalid API Key":** Double-check that you've entered the API key correctly.
- **"Model Not Found":** Make sure you're using a valid model ID for your chosen provider.
- **Connection Errors:** Verify the Base URL is correct and that your provider's API is accessible.
- **Unexpected Results:** If you're getting unexpected results, try a different model.
By using an OpenAI-compatible provider, you can leverage the flexibility of Kilo Code with a wider range of AI models. Remember to always consult your provider's documentation for the most accurate and up-to-date information.
@@ -0,0 +1,28 @@
---
sidebar_label: OpenAI
---
# Using OpenAI With Kilo Code
Kilo Code supports accessing models directly through the official OpenAI API.
**Website:** [https://openai.com/](https://openai.com/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [OpenAI Platform](https://platform.openai.com/). Create an account or sign in.
2. **Navigate to API Keys:** Go to the [API keys](https://platform.openai.com/api-keys) page.
3. **Create a Key:** Click "Create new secret key". Give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "OpenAI" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your OpenAI API key into the "OpenAI API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Pricing:** Refer to the [OpenAI Pricing](https://openai.com/pricing) page for details on model costs.
- **Azure OpenAI Service:** If you'd like to use the Azure OpenAI service, please see our section on [OpenAI-compatible](/docs/ai-providers/openai-compatible) providers.
@@ -0,0 +1,52 @@
---
sidebar_label: OpenRouter
---
# Using OpenRouter With Kilo Code
OpenRouter is an AI platform that provides access to a wide variety of language models from different providers, all through a single API. This can simplify setup and allow you to easily experiment with different models.
**Website:** [https://openrouter.ai/](https://openrouter.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [OpenRouter website](https://openrouter.ai/). Sign in with your Google or GitHub account.
2. **Get an API Key:** Go to the [keys page](https://openrouter.ai/keys). You should see an API key listed. If not, create a new key.
3. **Copy the Key:** Copy the API key.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "OpenRouter" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your OpenRouter API key into the "OpenRouter API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
5. **(Optional) Custom Base URL:** If you need to use a custom base URL for the OpenRouter API, check "Use custom base URL" and enter the URL. Leave this blank for most users.
## Supported Transforms
OpenRouter provides an [optional "middle-out" message transform](https://openrouter.ai/docs/features/message-transforms) to help with prompts that exceed the maximum context size of a model. You can enable it by checking the "Compress prompts and message chains to the context size" box.
## Provider Routing
OpenRouter can route to many different inference providers and this can be controlled in the API Provider settings under Provider Routing.
### Provider Sorting
- Default provider sorting: use the setting in your OpenRouter account
- Prefer providers with lower price
- Prefer providers with higher throughput (i.e. more tokens per seconds)
- Prefer providers with lower latency (i.e. shorter time to first token)
- A specific provider preference can also be chosen.
### Data Policy
- No data policy set: use the settings in your OpenRouter account.
- Allow prompt training: providers that may train on your prompts or completions are allowed. Free models generally require this option to be enabled.
- Deny prompt training: providers that may train on your prompts or completions are not allowed.
- Zero data retention: only providers with a strict zero data retention policy are allowed. This option is not recommended, as it will disable many popular providers, such as Anthropic and OpenAI.
## Tips and Notes
- **Model Selection:** OpenRouter offers a wide range of models. Experiment to find the best one for your needs.
- **Pricing:** OpenRouter charges based on the underlying model's pricing. See the [OpenRouter Models page](https://openrouter.ai/models) for details.
- **Prompt Caching:** Some providers support prompt caching. See the OpenRouter documentation for supported models.
@@ -0,0 +1,30 @@
---
sidebar_label: OVHcloud AI Endpoints
---
# Using OVHcloud AI Endpoints with Kilo Code
OVHcloud is a French leading Cloud provider in Europe with data sovereignty and privacy.
Access world-renowned pre-trained AI models with ease. Innovate using straightforward, secure APIs on OVHcloud's robust and privacy-first infrastructure. Enhance your applications with scalable AI capabilities, eliminating the need for extensive expertise. Achieve more with powerful AI endpoints designed for simplicity et reliability.
**Website:** [https://endpoints.ai.cloud.ovh.net](https://endpoints.ai.cloud.ovh.net)
{% callout type="info" %}
You can report any bugs or feedbacks by chatting with us in our [Discord server](https://discord.gg/ovhcloud), in the AI Endpoints channel.
{% /callout %}
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [OVHcloud manager](https://www.ovh.com/manager). Create an account or sign in.
2. **Navigate to Public Cloud:** Go to the Public Cloud section, and create a new project. Navigate to AI Endpoints in the _AI & Machine Learning_ section.
3. **Create a Key:** Click to _API keys_ and create a new key.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "OVHcloud AI Endpoints" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your AI Endpoints API key into the "OVHcloud AI Endpoints API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
@@ -0,0 +1,36 @@
---
sidebar_label: Requesty
---
# Using Requesty With Kilo Code
Kilo Code supports accessing models through the [Requesty](https://www.requesty.ai/) AI platform. Requesty provides an easy and optimized API for interacting with 150+ large language models (LLMs).
**Website:** [https://www.requesty.ai/](https://www.requesty.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [Requesty website](https://www.requesty.ai/) and create an account or sign in.
2. **Get API Key:** You can get an API key from the [API Management](https://app.requesty.ai/manage-api) section of your Requesty dashboard.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Requesty" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Requesty API key into the "Requesty API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Optimizations**: Requesty offers range of in-flight cost optimizations to lower your costs.
- **Unified and simplified billing**: Unrestricted access to all providers and models, automatic balance top ups and more via a single [API key](https://app.requesty.ai/manage-api).
- **Cost tracking**: Track cost per model, coding language, changed file, and more via the [Cost dashboard](https://app.requesty.ai/cost-management) or the [Requesty VS.code extension](https://marketplace.visualstudio.com/items?itemName=Requesty.requesty).
- **Stats and logs**: See your [coding stats dashboard](https://app.requesty.ai/usage-stats) or go through your [LLM interaction logs](https://app.requesty.ai/logs).
- **Fallback policies**: Keep your LLM working for you with fallback policies when providers are down.
* **Prompt Caching:** Some providers support prompt caching. [Search models with caching](https://app.requesty.ai/router/list).
## Relevant resources
- [Requesty Youtube channel](https://www.youtube.com/@requestyAI):
- [Requesty Discord](https://requesty.ai/discord)
@@ -0,0 +1,150 @@
---
sidebar_label: SAP AI Core
---
# Using SAP AI Core With Kilo Code
Kilo Code supports accessing models through SAP AI Core, a service in the SAP Business Technology Platform that lets you efficiently run AI scenarios in a standardized, scalable, and hyperscaler-agnostic manner.
**Website:** [https://help.sap.com/docs/sap-ai-core](https://help.sap.com/docs/sap-ai-core)
## Prerequisites
- **SAP BTP Account:** You need an active SAP Business Technology Platform account.
- **SAP AI Core Service:** You must have access to the SAP AI Core service in your BTP subaccount.
- **Service Instance:** Create a service instance of SAP AI Core with appropriate service plan.
- **Service Key:** Generate a service key for your SAP AI Core service instance to obtain the required credentials.
## Getting Credentials
To use SAP AI Core with Kilo Code, you'll need to create a service key for your SAP AI Core service instance:
1. **In SAP BTP Cockpit:**
- Navigate to your subaccount
- Go to "Services" → "Instances and Subscriptions"
- Find your SAP AI Core service instance
- Create a new service key
2. **Service Key Information:**
The service key will contain the following information you'll need:
- **Client ID:** OAuth2 client identifier
- **Client Secret:** OAuth2 client secret
- **Auth URL:** OAuth2 authentication endpoint
- **Base URL:** SAP AI Core API base URL
- **Resource Group:** (Optional) Specify a resource group, defaults to "default"
## Operating Modes
SAP AI Core provider supports two operating modes:
### Foundation Models Mode (Default)
- Uses foundation models that require active deployments
- Currently, supports **OpenAI models only** due to SAP AI Core SDK limitations
- Requires you to have running deployments for the models you want to use
- Models must have deployments in "RUNNING" status to be selectable
### Orchestration Mode
- Uses SAP AI Core's orchestration capabilities
- Supports models from multiple providers: **Amazon, Anthropic, Google, OpenAI, and Mistral AI**
- Does not require separate deployments
- Provides access to a broader range of models
## Model Requirements
Kilo Code applies the following filters when fetching models:
- **Streaming:** Models must support streaming
- **Capabilities:** Models must support text generation
- **Context Window:** Models must have a context window of at least 32,000 tokens
## Supported Providers
### Foundation Models Mode
- **OpenAI:** All OpenAI models with active deployments
### Orchestration Mode
- **Amazon:** Amazon foundation models
- **Anthropic:** Claude models
- **Google:** Gemini models
- **OpenAI:** ChatGPT and GPT models
- **Mistral AI:** Mistral AI models
The exact list of available models depends on your SAP AI Core configuration and active model offerings.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "SAP AI Core" from the "API Provider" dropdown.
3. **Enter Credentials:**
- **Client ID:** Enter your SAP AI Core OAuth2 client ID
- **Client Secret:** Enter your SAP AI Core OAuth2 client secret
- **Base URL:** Enter your SAP AI Core API base URL (e.g., `https://api.ai.ml.hana.ondemand.com`)
- **Auth URL:** Enter your SAP AI Core OAuth2 auth URL (e.g., `https://your-subdomain.authentication.sap.hana.ondemand.com`)
- **Resource Group:** (Optional) Enter your resource group name, defaults to "default"
4. **Choose Operating Mode:**
- **Orchestration Mode:** Check the "Use Orchestration" checkbox for broader model access
- **Foundation Models Mode:** Leave unchecked to use foundation models with deployments
5. **Select Model:** Choose your desired model from the dropdown
6. **Select Deployment:** (Foundation Models Mode only) Choose an active deployment for your selected model
## Deployments (Foundation Models Mode)
When using Foundation Models mode:
- You must have active deployments for the models you want to use
- Only deployments with "RUNNING" status are available for selection
- Deployments in other states (PENDING, STOPPED, etc.) are shown but disabled
- The interface displays the number of available deployments for each model
## Tips and Notes
- **Authentication:** SAP AI Core uses OAuth2 client credentials flow for authentication
- **Caching:** Model and deployment information is cached for 15 and 5 minutes respectively to improve performance
- **Resource Groups:** If you use multiple resource groups, specify the appropriate one in the configuration
- **Permissions:** Ensure your service key has the necessary permissions to access models and deployments
- **Orchestration Benefits:** Use Orchestration mode for access to a wider variety of models without managing deployments
- **Foundation Models Benefits:** Use Foundation Models mode when you need more control over specific model deployments
## Troubleshooting
### Common Issues
1. **Authentication Failures:**
- Verify your Client ID and Client Secret are correct
- Check that your Auth URL is properly formatted
- Ensure your service key hasn't expired
2. **No Models Available:**
- Check that you have the necessary permissions in your resource group
- Verify your Base URL is correct
- In Foundation Models mode, ensure you have running deployments
3. **Deployment Issues:**
- Check that your deployments are in "RUNNING" status
- Verify you're using the correct resource group
- Review your SAP AI Core service configuration
4. **Model Access:**
- In Foundation Models mode, **only OpenAI models** are currently supported
- Switch to Orchestration mode for access to other providers
- Ensure models meet the minimum requirements (32k context window, streaming support)
## Getting Started
To get started with SAP AI Core:
1. Set up your SAP BTP account and access SAP AI Core service
2. Create a service instance and generate a service key
3. Configure Kilo Code with your credentials
4. Choose between Foundation Models or Orchestration mode based on your needs
5. Select an appropriate model and start coding
For detailed setup instructions and service configuration, visit the [SAP AI Core documentation](https://help.sap.com/docs/sap-ai-core).
@@ -0,0 +1,34 @@
---
sidebar_label: Synthetic
---
# Using Synthetic With Kilo Code
Synthetic provides access to several open-source AI models running on secure infrastructure within the US and EU. They offer both subscription-based and usage-based pricing options, with strong privacy guarantees - they never train on your data and auto-delete API data within 14 days.
**Website:** [https://synthetic.new](https://synthetic.new)
## Getting an API Key
1. **Sign Up/Sign In:** Go to [Synthetic](https://synthetic.new) and create an account or sign in.
2. **Navigate to API Keys:** After logging in, go to the [API Keys page](https://synthetic.new/user-settings/api) in your account settings.
3. **Copy your Key:** Click the Copy icon next to your key to copy it to your clipboard.
## Supported Models
Kilo Code supports all "always on" Synthetic AI models. The available models include various open-source options optimized for different use cases.
**Note:** Model availability may change. Refer to the [Synthetic documentation](https://synthetic.new) for the most up-to-date list of supported models and their capabilities.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Synthetic" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Synthetic API key into the "Synthetic API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Pricing Options:** Synthetic offers both subscriptions and pay-as-you-go usage-based [pricing](https://synthetic.new/pricing).
- **Privacy:** Strong privacy policy with no training on user data and automatic deletion of API data within 14 days.
- **OpenAI Compatibility:** Synthetic models work with any OpenAI-compatible tools and applications.
@@ -0,0 +1,30 @@
---
sidebar_label: Unbound
---
# Using Unbound With Kilo Code
Kilo Code supports accessing models through [Unbound](https://getunbound.ai/), a platform that focuses on providing secure and reliable access to a variety of large language models (LLMs). Unbound acts as a gateway, allowing you to use models from providers like Anthropic and OpenAI without needing to manage multiple API keys and configurations directly. They emphasize security and compliance features for enterprise use.
**Website:** [https://getunbound.ai/](https://getunbound.ai/)
## Creating an Account
1. **Sign Up/Sign In:** Go to the [Unbound gateway](https://gateway.getunbound.ai). Create an account or sign in.
2. **Create an Application:** Go to the [Applications](https://gateway.getunbound.ai/ai-gateway-applications) page and hit the "Create Application" button.
3. **Copy the API Key:** Copy the API key to your clipboard.
## Supported Models
Unbound allows you configure a list of supported models in your application, and Kilo Code will automatically fetch the list of available models from the Unbound API.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Unbound" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Unbound API key into the "Unbound API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Security Focus:** Unbound emphasizes security features for enterprise use. If your organization has strict security requirements for AI usage, Unbound might be a good option.
@@ -0,0 +1,39 @@
---
sidebar_label: v0
---
# Using v0 With Kilo Code
Kilo Code supports v0, Vercel's AI model provider that offers an OpenAI-compatible API. This allows you to use v0's models with Kilo Code through the familiar OpenAI API interface.
## Prerequisites
To use v0 with Kilo Code, you'll need:
- A team account with Vercel v0
- A v0 API key
## Configuration
Setting up v0 in Kilo Code is straightforward:
1. In Kilo Code settings (click the {% codicon name="gear" /%} icon):
- Under **API Provider**, select: **OpenAI Compatible**
- Set the **Base URL**: `https://api.v0.dev/v1`
- Paste in your v0 API key
- Set the **Model ID**: `v0-1.0-md`
- Click **Verify** to confirm the connection
<!-- <img src="/docs/img/providers/v0-setup.png" alt="v0 configuration in Kilo Code settings" width="600" /> -->
## Troubleshooting
- **"Invalid API Key":** Double-check that you've entered the API key correctly.
- **"Model Not Found":** Make sure you're using the correct model ID (`v0-1.0-md`).
- **Connection Errors:** Verify the Base URL is correct (`https://api.v0.dev/v1`).
- **Access Issues:** Confirm that your Vercel v0 team account is active and properly set up.
## Additional Resources
- [v0 Official Documentation](https://v0.dev)
- [Vercel AI Documentation](https://vercel.com/docs/ai)
@@ -0,0 +1,76 @@
---
description: Configure the Vercel AI Gateway in Kilo Code to robustly access 100+ language models from various providers through a centralized interface.
keywords:
- kilo code
- vercel ai gateway
- ai provider
- language models
- api configuration
- model selection
- prompt caching
- usage tracking
- byok
sidebar_label: Vercel AI Gateway
---
# Using Vercel AI Gateway With Kilo Code
The AI Gateway provides a unified API to access hundreds of models through a single endpoint. It gives you the ability to set budgets, monitor usage, load-balance requests, and manage fallbacks.
Useful links:
- Team dashboard: https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai
- Models catalog: https://vercel.com/ai-gateway/models
- Docs: https://vercel.com/docs/ai-gateway
---
## Getting an API Key
An API key is required for authentication.
1. **Sign Up/Sign In:** Go to the [Vercel Website](https://vercel.com/) and sign in.
2. **Get an API Key:** Go to the [API Key page](https://vercel.com/d?to=%2F%5Bteam%5D%2F%7E%2Fai%2Fapi-keys&title=AI+Gateway+API+Key) in the AI Gateway tab. Create a new key.
3. **Copy the Key:** Copy the API key.
---
## Supported Models
The Vercel AI Gateway supports a large and growing number of models. Kilo Code automatically fetches the list of available models from the `https://ai-gateway.vercel.sh/v1/models` endpoint. Only language models are shown.
The default model is `anthropic/claude-sonnet-4` if no model is selected.
Refer to the [Vercel AI Gateway Models page](https://vercel.com/ai-gateway/models) for the complete and up-to-date list.
### Model Capabilities
- **Vision Support**: Many models support image inputs.
- **Tool/Computer Use**: Select models support function calling and computer use.
Check the model description in the dropdown for specific capabilities.
---
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Vercel AI Gateway" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your Vercel AI Gateway API key into the "Vercel AI Gateway API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
---
## Prompt Caching
Vercel AI Gateway supports automatic prompt caching for select models including Anthropic Claude and OpenAI GPT models. This reduces costs by caching frequently used prompts.
---
## Tips and Notes
- **Model Selection:** The Vercel AI Gateway offers a wide range of models. Experiment to find the best one for your needs.
- **Pricing:** The Vercel AI Gateway charges based on the underlying model's pricing, including costs for cached prompts. See the [Vercel AI Gateway Models page](https://vercel.com/ai-gateway/models) for details.
- **Temperature:** The default temperature is `0.7` and is configurable per model.
- **Bring Your Own Key (BYOK):** The Vercel AI Gateway has **no markup** if you decide to use your own key for the underlying service.
- **More info:** Vercel does not add rate limits. Upstream providers may. New accounts receive $5 credits every 30 days until the first payment.
@@ -0,0 +1,37 @@
---
sidebar_label: GCP Vertex AI
---
# Using GCP Vertex AI With Kilo Code
Kilo Code supports accessing models through Google Cloud Platform's Vertex AI, a managed machine learning platform that provides access to various foundation models, including Anthropic's Claude family.
**Website:** [https://cloud.google.com/vertex-ai](https://cloud.google.com/vertex-ai)
## Prerequisites
- **Google Cloud Account:** You need an active Google Cloud Platform (GCP) account.
- **Project:** You need a GCP project with the Vertex AI API enabled.
- **Model Access:** You must request and be granted access to the specific Claude models on Vertex AI you want to use. See the [Google Cloud documentation](https://cloud.google.com/vertex-ai/generative-ai/docs/partner-models/use-claude#before_you_begin) for instructions.
- **Application Default Credentials (ADC):** Kilo Code uses Application Default Credentials to authenticate with Vertex AI. The easiest way to set this up is to:
1. Install the Google Cloud CLI: [https://cloud.google.com/sdk/docs/install](https://cloud.google.com/sdk/docs/install)
2. Authenticate using: `gcloud auth application-default login`
- **Service Account Key (Alternative):** Alternatively, you can authenticate using a Google Cloud Service Account key file. You'll need to generate this key in your GCP project. See the [Google Cloud documentation on creating service account keys](https://cloud.google.com/iam/docs/creating-managing-service-account-keys).
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "GCP Vertex AI" from the "API Provider" dropdown.
3. **Configure Authentication:**
- **If using Application Default Credentials (ADC):** No further action is needed here. ADC will be used automatically if configured correctly (see Prerequisites).
- **If _not_ using ADC (Service Account Key):**
- **Option A: Paste JSON Content:** Paste the entire content of your Service Account JSON key file into the **Google Cloud Credentials** field.
- **Option B: Provide File Path:** Enter the absolute path to your downloaded Service Account JSON key file in the **Google Cloud Key File Path** field.
4. **Enter Project ID:** Enter your Google Cloud Project ID.
5. **Select Region:** Choose the region where your Vertex AI resources are located (e.g., `us-east5`).
6. **Select Model:** Choose your desired model from the "Model" dropdown.
## Tips and Notes
- **Permissions:** Ensure your Google Cloud account has the necessary permissions to access Vertex AI and the specific models you want to use.
- **Pricing:** Refer to the [Vertex AI pricing](https://cloud.google.com/vertex-ai/pricing) page for details.
@@ -0,0 +1,78 @@
---
sidebar_label: Virtual Quota Fallback
---
# Using the Virtual Quota Fallback Provider
The Virtual Quota Fallback provider is a powerful meta-provider that allows you to configure and manage multiple API providers, automatically switching between them based on predefined usage limits and availability. This ensures you can maximize your usage of free-tier services and maintain continuous access to AI models by seamlessly falling back to other providers when one reaches its quota or encounters an error.
It's the perfect solution for users who leverage multiple LLM services and want to orchestrate them intelligently—for example, using a free provider up to its limit before automatically switching to a pay-as-you-go service.
## How It Works
The Virtual Quota Fallback provider does not connect to an LLM service directly. Instead, it acts as a manager for your other configured provider profiles.
- **Prioritized List:** You create a prioritized list of your existing provider profiles. The provider at the top of the list is used first.
- **Usage Tracking:** You can set custom limits for each provider based on the number of tokens or requests per minute, hour, or day. Kilo Code tracks the usage for each provider against these limits.
- **Automatic Fallback:** When the currently active provider exceeds one of its defined limits or returns an API error, the system automatically deactivates it temporarily and switches to the next available provider in your list.
- **Notifications:** You will receive an information message in VS Code whenever an automatic switch occurs, keeping you informed of which provider is currently active.
## Prerequisites
Before configuring this provider, you must have at least one other API provider already configured as a separate profile in Kilo Code. This provider is only useful if there are other profiles for it to manage.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "Virtual Quota Fallback" from the "API Provider" dropdown. This will open its dedicated configuration panel.
<!-- <img src="/docs/img/providers/virtualQuotaSelectDropdown.png" alt="virtuaQuotaFallback dropdown selection in Kilo Code settings" width="600" /> -->
3. **Add a Provider Profile:**
- In the configuration panel, click the **"Add Profile"** button to create a new entry in the list.
- Click the dropdown menu on the new entry to select one of your other pre-configured provider profiles (e.g., "OpenAI", "Chutes AI Free Tier").
4. **Set Usage Limits (Optional):**
- Once a profile is added, you can specify usage limits. If you leave these fields blank, no limit will be enforced for that specific metric.
- **Tokens per minute/hour/day:** Limits usage based on the total number of tokens processed (input + output).
- **Requests per minute/hour/day:** Limits the total number of API calls made.
5. **Order Your Providers:**
- The order of the profiles is crucial, as it defines the fallback priority. The provider at the top is used first.
- Use the **up and down arrows** next to each profile to change its position in the list.
6. **Add More Providers:** Repeat steps 3-5 to build your complete fallback chain. You can add as many profiles as you have configured.
<!-- <img src="/docs/img/providers/virtualQuotaFullConfig.png" alt="virtuaQuotaFallback configuration in Kilo Code settings" width="600" /> -->
## Usage Monitoring
The configuration screen also serves as a dashboard for monitoring the current usage of each provider in your list.
- You can see the tokens and requests used within the last minute, hour, and day.
- If you need to reset these counters, click the **"Clear Usage Data"** button. This will reset all statistics to zero and immediately re-enable any providers that were temporarily disabled due to exceeding their limits.
## Example Use Case
Imagine you have two profiles configured:
1. **Chutes AI Free:** A free-tier provider with a limit of 5,000 tokens per hour.
2. **OpenAI Paid:** Your personal pay-as-you-go OpenAI account.
**Configuration:**
- Place "Chutes AI Free" first in the list.
- Set its "Tokens per hour" limit to `5000`.
- Place "OpenAI Paid" second in the list, with no limits defined.
**Result:**
Kilo Code will send all requests to Chutes AI. Once your usage exceeds 5,000 tokens within an hour, it will automatically switch to your OpenAI account. The system will switch back to Chutes AI in the next hour when its quota window has reset.
## Tips and Notes
- **Priority is Key:** Always double-check the order of your profiles. The intended primary or free-tier providers should be at the top.
- **Error-Based Fallback:** If you don't set any limits for a profile, fallback will only occur if the provider's API returns an error (e.g., a hard rate limit from the service itself, a network issue, or an invalid API key).
- **No Nesting:** You cannot select another "Virtual Quota Fallback" profile within this provider's configuration, as this would create a circular dependency.
@@ -0,0 +1,45 @@
---
sidebar_label: VS Code Language Model API
---
# Using VS Code Language Model API With Kilo Code
Kilo Code includes _experimental_ support for the [VS Code Language Model API](https://code.visualstudio.com/api/language-extensions/language-model-access). This API allows extensions to provide access to language models directly within VS Code. This means you can potentially use models from:
- **GitHub Copilot:** If you have a Copilot subscription and the extension installed.
- **Other VS Code Extensions:** Any extension that implements the Language Model API.
**Important:** This integration is highly experimental and may not work as expected. It is dependent on other extensions correctly implementing the VS Code Language Model API.
## Prerequisites
- **VS Code:** The Language Model API is available through VS Code (and is not currently supported by Cursor).
- **A Language Model Provider Extension:** You need an extension that provides a language model. Examples include:
- **GitHub Copilot:** If you have a Copilot subscription, the GitHub Copilot and GitHub Copilot Chat extensions can provide models.
- **Other Extensions:** Search the VS Code Marketplace for extensions that mention "Language Model API" or "lm". There may be other experimental extensions available.
## Configuration
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "VS Code LM API" from the "API Provider" dropdown.
3. **Select Model:** The "Language Model" dropdown will (eventually) list available models. The format is `vendor/family`. For example, if you have Copilot, you might see options like:
- `copilot - claude-3.5-sonnet`
- `copilot - o3-mini`
- `copilot - o1-ga`
- `copilot - gemini-2.0-flash`
## Limitations
- **Experimental API:** The VS Code Language Model API is still under development. Expect changes and potential instability.
- **Extension Dependent:** This feature relies entirely on other extensions providing models. Kilo Code cannot directly control which models are available.
- **Limited Functionality:** The VS Code Language Model API may not support all the features of other API providers (e.g., image input, streaming, detailed usage information).
- **No Direct Cost Control:** You are subject to the pricing and terms of the extension providing the model. Kilo Code cannot directly track or limit costs.
- **GitHub Copilot Rate Limits:** When using the VS Code LM API with GitHub Copilot, be aware that GitHub may impose rate limits on Copilot usage. These limits are controlled by GitHub, not Kilo Code.
## Troubleshooting
- **No Models Appear:**
- Ensure you have VS Code installed.
- Ensure you have a language model provider extension installed and enabled (e.g., GitHub Copilot, GitHub Copilot Chat).
- If using Copilot, make sure that you have sent a Copilot Chat message using the model you would like to use.
- **Unexpected Behavior:** If you encounter unexpected behavior, it's likely an issue with the underlying Language Model API or the provider extension. Consider reporting the issue to the provider extension's developers.
@@ -0,0 +1,49 @@
---
sidebar_label: xAI (Grok)
---
# Using xAI (Grok) With Kilo Code
xAI is the company behind Grok, a large language model known for its conversational abilities and large context window. Grok models are designed to provide helpful, informative, and contextually relevant responses.
**Website:** [https://x.ai/](https://x.ai/)
## Getting an API Key
1. **Sign Up/Sign In:** Go to the [xAI Console](https://console.x.ai/). Create an account or sign in.
2. **Navigate to API Keys:** Go to the API keys section in your dashboard.
3. **Create a Key:** Click to create a new API key. Give your key a descriptive name (e.g., "Kilo Code").
4. **Copy the Key:** **Important:** Copy the API key _immediately_. You will not be able to see it again. Store it securely.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon ({% codicon name="gear" /%}) in the Kilo Code panel.
2. **Select Provider:** Choose "xAI" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your xAI API key into the "xAI API Key" field.
4. **Select Model:** Choose your desired Grok model from the "Model" dropdown.
## Reasoning Capabilities
Some models feature specialized reasoning capabilities, allowing them to "think before responding" - particularly useful for complex problem-solving tasks.
### Controlling Reasoning Effort
When using reasoning-enabled models, you can control how hard the model thinks with the `reasoning_effort` parameter:
- `low`: Minimal thinking time, using fewer tokens for quick responses
- `high`: Maximum thinking time, leveraging more tokens for complex problems
Choose `low` for simple queries that should complete quickly, and `high` for harder problems where response latency is less important.
### Key Features
- **Step-by-Step Problem Solving**: The model thinks through problems methodically before delivering an answer
- **Math & Quantitative Strength**: Excels at numerical challenges and logic puzzles
- **Reasoning Trace Access**: The model's thinking process is available via the `reasoning_content` field in the response completion object
## Tips and Notes
- **Context Window:** Most Grok models feature large context windows (up to 131K tokens), allowing you to include substantial amounts of code and context in your prompts.
- **Vision Capabilities:** Select vision-enabled models (`grok-2-vision-latest`, `grok-2-vision`, etc.) when you need to process or analyze images.
- **Pricing:** Pricing varies by model, with input costs ranging from $0.3 to $5.0 per million tokens and output costs from $0.5 to $25.0 per million tokens. Refer to the xAI documentation for the most current pricing information.
- **Performance Tradeoffs:** "Fast" variants typically offer quicker response times but may have higher costs, while "mini" variants are more economical but may have reduced capabilities.
@@ -0,0 +1,197 @@
---
title: ZenMux
---
import Codicon from "@site/src/components/Codicon";
# Using ZenMux With Kilo Code
[ZenMux](https://zenmux.ai) provides a unified API gateway to access multiple AI models from different providers through a single endpoint. It supports OpenAI, Anthropic, Google, and other major AI providers, automatically handling routing, fallbacks, and cost optimization.
## Getting Started
1. **Sign up for ZenMux:** Visit [zenmux.ai](https://zenmux.ai) to create an account.
2. **Get your API key:** After signing up, navigate to your dashboard to generate an API key.
3. **Configure in Kilo Code:** Add your API key to Kilo Code settings.
## Configuration in Kilo Code
1. **Open Kilo Code Settings:** Click the gear icon (<Codicon name="gear" />) in the Kilo Code panel.
2. **Select Provider:** Choose "ZenMux" from the "API Provider" dropdown.
3. **Enter API Key:** Paste your ZenMux API key into the "ZenMux API Key" field.
4. **Select Model:** Choose your desired model from the "Model" dropdown.
5. **(Optional) Custom Base URL:** If you need to use a custom base URL for the ZenMux API, check "Use custom base URL" and enter the URL. Leave this blank for most users.
## Supported Models
ZenMux supports a wide range of models from various providers:
Visi [zenmux.ai/models](https://zenmux.ai/models) to see the complete list of available models.
### Other Providers
ZenMux also supports models from Meta, Mistral, and many other providers. Check your ZenMux dashboard for the complete list of available models.
## API Compatibility
ZenMux provides multiple API endpoints for different protocols:
### OpenAI Compatible API
Use the standard OpenAI SDK with ZenMux's base URL:
```javascript
import OpenAI from "openai"
const openai = new OpenAI({
baseURL: "https://zenmux.ai/api/v1",
apiKey: "<ZENMUX_API_KEY>",
})
async function main() {
const completion = await openai.chat.completions.create({
model: "openai/gpt-5",
messages: [
{
role: "user",
content: "What is the meaning of life?",
},
],
})
console.log(completion.choices[0].message)
}
main()
```
### Anthropic API
For Anthropic models, use the dedicated endpoint:
```typescript
import Anthropic from "@anthropic-ai/sdk"
// 1. Initialize the Anthropic client
const anthropic = new Anthropic({
// 2. Replace with the API key from your ZenMux console
apiKey: "<YOUR ZENMUX_API_KEY>",
// 3. Point the base URL to the ZenMux endpoint
baseURL: "https://zenmux.ai/api/anthropic",
})
async function main() {
const msg = await anthropic.messages.create({
model: "anthropic/claude-sonnet-4.5",
max_tokens: 1024,
messages: [{ role: "user", content: "Hello, Claude" }],
})
console.log(msg)
}
main()
```
### Platform API
The Get generation interface is used to query generation information, such as usage and costs.
```bash
curl https://zenmux.ai/api/v1/generation?id=<generation_id> \
-H "Authorization: Bearer $ZENMUX_API_KEY"
```
### Google Vertex AI API
For Google models:
```typescript
const genai = require("@google/genai")
const client = new genai.GoogleGenAI({
apiKey: "$ZENMUX_API_KEY",
vertexai: true,
httpOptions: {
baseUrl: "https://zenmux.ai/api/vertex-ai",
apiVersion: "v1",
},
})
const response = await client.models.generateContent({
model: "google/gemini-2.5-pro",
contents: "How does AI work?",
})
console.log(response)
```
## Features
### Automatic Routing
ZenMux automatically routes your requests to the best available provider based on:
- Model availability
- Response time
- Cost optimization
- Provider health status
### Fallback Support
If a provider is unavailable, ZenMux automatically falls back to alternative providers that support the same model capabilities.
### Cost Optimization
ZenMux can be configured to optimize for cost, routing requests to the most cost-effective provider while maintaining quality.
### Zero Data Retention (ZDR)
Enable ZDR mode to ensure that no request or response data is stored by ZenMux, providing maximum privacy for sensitive applications.
## Advanced Configuration
### Provider Routing
You can specify routing preferences:
- **Price**: Route to the lowest cost provider
- **Throughput**: Route to the provider with highest tokens/second
- **Latency**: Route to the provider with fastest response time
### Data Collection Settings
Control how ZenMux handles your data:
- **Allow**: Allow data collection for service improvement
- **Deny**: Disable all data collection
### Middle-Out Transform
Enable the middle-out transform feature to optimize prompts that exceed model context limits.
## Troubleshooting
### API Key Issues
- Ensure your API key is correctly copied without any extra spaces
- Check that your ZenMux account is active and has available credits
- Verify the API key has the necessary permissions
### Model Availability
- Some models may have regional restrictions
- Check the ZenMux dashboard for current model availability
- Ensure your account tier has access to the desired models
### Connection Issues
- Verify your internet connection
- Check if you're behind a firewall that might block API requests
- Try using a custom base URL if the default endpoint is blocked
## Support
For additional support:
- Visit the [ZenMux documentation](https://zenmux.ai/docs)
- Contact ZenMux support through their dashboard
- Check the [Kilo Code GitHub repository](https://github.com/kilocode/kilocode) for integration-specific issues
+85
View File
@@ -0,0 +1,85 @@
import type { NextApiRequest, NextApiResponse } from "next"
import fs from "fs"
import path from "path"
/**
* Recursively finds all markdown files in a directory
*/
function findMarkdownFiles(dir: string, baseDir: string = dir): string[] {
const files: string[] = []
const entries = fs.readdirSync(dir, { withFileTypes: true })
for (const entry of entries) {
const fullPath = path.join(dir, entry.name)
if (entry.isDirectory()) {
// Skip api directory
if (entry.name === "api") continue
files.push(...findMarkdownFiles(fullPath, baseDir))
} else if (entry.name.endsWith(".md")) {
files.push(fullPath)
}
}
return files
}
/**
* Converts a file path to a URL path
*/
function filePathToUrlPath(filePath: string, pagesDir: string): string {
let relativePath = path.relative(pagesDir, filePath)
// Remove .md extension
relativePath = relativePath.replace(/\.md$/, "")
// Handle index files
relativePath = relativePath.replace(/\/index$/, "")
// Convert to URL path
return "/" + relativePath
}
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "GET") {
return res.status(405).json({ error: "Method not allowed" })
}
try {
const pagesDir = path.join(process.cwd(), "pages")
const markdownFiles = findMarkdownFiles(pagesDir)
// Sort files for consistent output
markdownFiles.sort()
const sections: string[] = []
// Add header
sections.push("# Kilo Code Documentation")
sections.push("")
sections.push(
"This file contains the complete documentation for Kilo Code, the leading open source agentic engineering platform.",
)
sections.push("")
sections.push("---")
sections.push("")
for (const filePath of markdownFiles) {
const urlPath = filePathToUrlPath(filePath, pagesDir)
const content = fs.readFileSync(filePath, "utf-8")
sections.push(`## Source: ${urlPath}`)
sections.push("")
sections.push(content)
sections.push("")
sections.push("---")
sections.push("")
}
const output = sections.join("\n")
res.setHeader("Content-Type", "text/plain; charset=utf-8")
res.setHeader("Cache-Control", "public, max-age=3600") // Cache for 1 hour
res.status(200).send(output)
} catch (error) {
console.error("Error generating llms.txt:", error)
res.status(500).json({ error: "Internal server error" })
}
}
@@ -0,0 +1,49 @@
import type { NextApiRequest, NextApiResponse } from "next"
import fs from "fs"
import path from "path"
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== "GET") {
return res.status(405).json({ error: "Method not allowed" })
}
const { path: mdPath } = req.query
if (!mdPath || typeof mdPath !== "string") {
return res.status(400).json({ error: "Missing path parameter" })
}
try {
// Normalize the path to resolve traversal sequences before checking bounds
const sanitizedPath = path.normalize(mdPath).replace(/^\/+/, "")
const pagesDir = path.join(process.cwd(), "pages")
const resolvedPagesDir = path.resolve(pagesDir)
// Verify bounds BEFORE any filesystem probes to prevent info leakage
const candidatePath = path.resolve(pagesDir, `${sanitizedPath}.md`)
const candidateIndexPath = path.resolve(pagesDir, sanitizedPath, "index.md")
if (!candidatePath.startsWith(resolvedPagesDir) || !candidateIndexPath.startsWith(resolvedPagesDir)) {
return res.status(403).json({ error: "Access denied" })
}
// Now safe to probe filesystem
let resolvedPath = candidatePath
if (!fs.existsSync(resolvedPath)) {
resolvedPath = candidateIndexPath
}
if (!fs.existsSync(resolvedPath)) {
return res.status(404).json({ error: "File not found" })
}
const content = fs.readFileSync(resolvedPath, "utf-8")
res.setHeader("Content-Type", "text/plain; charset=utf-8")
res.status(200).send(content)
} catch (error) {
console.error("Error reading markdown file:", error)
res.status(500).json({ error: "Internal server error" })
}
}

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